Actualmente estoy tratando de analizar algunas entradas de usuarios en algunos grupos de expresiones regulares para poder poner las siguientes entradas en las salidas.
La expresión regular actual que tengo es
^[0-9]+[d,D,h,H,m,M]$ Esto coincide con éxito con una sola fecha, por ejemplo, 1d o 2h . Sin embargo, necesito que funcione dinámicamente para cada uno, incluso si el usuario no proporciona algunos.
input: "5d" output: {days: 5, hours: 0, minutes: 0} input: "1d 2h" output: {days: 1, hours: 2, minutes: 0} input: "1d 5h 2m" output: {days: 1, hours: 5, minutes: 2} input: "2m" output: {days: 0, hours: 0, minutes: 2}La salida no necesariamente tiene que estar en un objeto js, simplemente usar grupos de expresiones regulares también sería beneficioso y algo con lo que podría trabajar.
Cualquier ayuda sería muy apreciada ya que no estoy seguro de qué más hacer.
Puede expandir su expresión regular para incluir tres grupos de captura con nombre para los días, horas y minutos, luego use los valores de grupo para completar un objeto de salida:
const parseInterval = s => { let res = regex.exec(s) || {} return { days : +res.groups.days || 0, hours : +res.groups.hours || 0, minutes : +res.groups.minutes || 0 } } const input = [ "5d", "1D 2h", "1d 5H 2m", "2M"] const regex = /(?:(?<days>\d+)d)?\s*(?:(?<hours>\d+)h)?\s*(?:(?<minutes>\d+)m)?/i const result = input.map(parseInterval) console.log(result)Puede usar RegExp.exec() para obtener todas las coincidencias globales con una sola expresión regular:
function parseDate(input) { const reg = /([0-9]+)([dhm])(?=[0-9\s]|$)/gi, result = {days: 0, hours: 0, minutes: 0}, map = {d: "days", h: "hours", m: "minutes"}; let match; while((match = reg.exec(input.value))) result[map[match[2]]] += +match[1]; //this will sum multiple matched values ie "1d 2d 3d" will become 6 days remove "+" from "+=" if this behaviour is not desired console.clear(); console.log(result); } parseDate(dateInput); <input id="dateInput" oninput="parseDate(this)" value="3d 2h 1m">Aquí hay una manera si puede vivir con 3 expresiones regulares para llenar el objeto:
let input = [ '5d', // {days: 5, hours: 0, minutes: 0} '1d 2h', // {days: 1, hours: 2, minutes: 0} '1d 5h 2m', // {days: 1, hours: 5, minutes: 2} '2m' // {days: 0, hours: 0, minutes: 2} ].forEach(str => { let d = str.match(/\b([0-9]+)d\b/); let h = str.match(/\b([0-9]+)h\b/); let m = str.match(/\b([0-9]+)m\b/); let obj = { days: d ? Number(d[1]) : 0, hours: h ? Number(h[1]) : 0, minutes: m ? Number(m[1]) : 0, } console.log(str + ' => ' + JSON.stringify(obj)); });Resultado:
5d => {"days":5,"hours":0,"minutes":0} 1d 2h => {"days":1,"hours":2,"minutes":0} 1d 5h 2m => {"days":1,"hours":5,"minutes":2} 2m => {"days":0,"hours":0,"minutes":2}