Tengo una cadena de plantilla que tiene campos de combinación:
Ejemplo:
let templateStr = '[!field]: value entered is too large. (max length=[!limit])';Tengo una cadena de mensaje de error que sigue el formato de plantilla mencionado anteriormente, aquí el nombre del campo y la longitud máxima pueden variar según el campo que el usuario está tratando de guardar.
Ejemplo:
let errorMessage = 'Country: value entered is too large. (max length=80)';Aquí estoy tratando de extraer las variables (campo, límite) a las que se hace referencia en templateStr en función del mensaje de error .
extractTemplateVar(errorMessage, templateStr) // should return field='Country' and limit='80' if errorMessage = 'Email: value entered is too large. (max length=100); después,
extractTemplateVar(errorMessage, templateStr) // should return field='Email' and limit='100'Intenté usar expresiones regulares para hacer coincidir y extraer variables de una cadena según la plantilla. no funciona según lo previsto
let pattern = '(.+): data value too large: .*(max length=(.+))'; new RegExp(pattern ).exec(errorMessage);Chicos, por favor ayúdenme a resolver este problema. Gracias de antemano chicos.
Esta es una tarea novedosa de hecho. Estos son los pasos que tomaría para abordar esto:
[!TEMPLATE_NAME] ) usando expresiones regularesY aquí está su código:
let templateStr = '[!field]: value entered is too large. (max length=[!limit])'; let errorMessage = 'Country: value entered is too large. (max length=80)'; function extractTemplateVar(str, template) { const match = /\[!.+?\]/g, data = [], result = {}, escapeRegex = str => str.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&"); let matching; while(matching = match.exec(template)) { // go through everything that looks like a template and get the text before and after it const index = matching.index; const str = matching[0]; const text = str.match(/(?<=\[!).+?(?=\])/)[0]; // extract the exact text from the template const endIndex = str.length + index; const front = escapeRegex(template.substr(0, index).replace(/\[!.+?\]/g, "::TMP::")); // text before const back = escapeRegex(template.substr(endIndex).replace(/\[!.+?\]/g, "::TMP::")); // text after data.push({ text, back, front }); } data.forEach(n => { const re = new RegExp(`(?<=${n.front.replaceAll("::TMP::", ".*?")}).+?(?=${n.back.replaceAll("::TMP::", ".*?")})`); // create regex with dynamic lookaround const findText = str.match(re)[0]; result[n.text] = findText; }); return result; } console.log(extractTemplateVar(errorMessage, templateStr));Según sus cadenas de ejemplo, como patrón podría usar 2 grupos de captura:
([^:\n]+):.*?\(max length=([^\s=()]+)\)El patrón coincide:
([^:]+) Capturar grupo 1 , hacer coincidir 1+ veces cualquier carácter excepto : o salto de línea:.*? Partido : y el resto de la línea no codiciosos\(max length= Coincidencia (max length=([^\s=()]+) Capturar grupo 2 , hacer coincidir 1+ veces cualquier carácter excepto = ( )\) Partido )Demostración de expresiones regulares
const regex = /([^:\n]+):.*?\(max length=([^\s=()]+)\)/; const errorMessage = 'Email: value entered is too large. (max length=100)'; const m = errorMessage.match(regex); if (m) { console.log(`field='${m[1]}' and limit='${m[2]}'`); } Si desea hacer coincidir solo dígitos para el límite, también puede usar \d+
([^:\n]+):.*?\(max length=(\d+)\)Esto es un poco asqueroso. Podría haber una mejor manera.
Parte 1, extraiga los nombres de las variables de la plantilla.
Parte 2, divida la plantilla por esos nombres para obtener el "resto de la plantilla"
Parte 3, convierta los fragmentos del "resto de la plantilla" a un formato compatible con expresiones regulares. Probablemente me perdí algunas cosas que necesitan ser escapadas
Parte 4, vuelva a unir los fragmentos de la plantilla a una cadena compatible con expresiones regulares, separados por (.*?), que capturará los valores reales de las variables.
Parte 5, ejecute la expresión regular construida contra el mensaje, para extraer valores variables
Parte 6, genere una estructura de retorno a partir de los nombres y valores de las variables
let templateStr = '[!field]: value entered is too large. (max length=[!limit])'; let errorMessage = 'Country: value entered is too large. (max length=80)'; const extractTemplateVars = (template, message) => { let regex = /\[\!(.*?)\]/g; let splitRegex = /\[\!.*?\]/g; let match, matches = []; // Part 1 while (match = regex.exec(template)) { matches.push(match[1]); } // Part 2 let arr = template.split(splitRegex); // Part 3 arr = arr.map(s => s.replaceAll("\\", "\\\\") .replaceAll("(", "\\(") .replaceAll(")", "\\)") .replaceAll(".", "\\.") ); // Part 4 let reStr = arr.join("(.*?)"); let re = new RegExp(reStr, "g"); // Part 5 let m = re.exec(message); let [garbage, ...values] = m; // Part 6 let output = matches.map((match, i) => ({[match]: values[i]})); console.log(output); }; extractTemplateVars(templateStr, errorMessage);