Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

264
Vistas
Extract variables from string based on template

I have a template string which has merge fields:

Example:

let templateStr = '[!field]: value entered is too large. (max length=[!limit])';

I have an error message string which follows the above mentioned template format, here the field name and max length can vary according to the field that user is trying to save.

Example:

let errorMessage = 'Country: value entered is too large. (max length=80)';

Here I am trying to extract the variables (field, limit) referenced in the templateStr based on the errorMessage.

extractTemplateVar(errorMessage, templateStr) // should return field='Country' and limit='80'

if errorMessage = 'Email: value entered is too large. (max length=100); then,

extractTemplateVar(errorMessage, templateStr) // should return field='Email' and limit='100'

I have tried using regex, to match and extract variables from string based on template. its not working as intended

let pattern = '(.+): data value too large: .*(max length=(.+))';
new RegExp(pattern ).exec(errorMessage);

Guys, please help me resolve this issue. Thanks in advance guys.

about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

This is a novel task indeed. Here's the steps I'd take to tackle this:

  1. Extract templates ([!TEMPLATE_NAME]) using regex
  2. In the template string, get all the text before and after the template, later to be used in regex lookarounds
  3. Create a regex with dynamic lookarounds. Note that we escaped the regular text to avoid strange behavior in our regex
  4. Match the text inside the given string and use it
  5. $$$ Profit! $$$

And here's your code:

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));

about 4 years ago · Juan Pablo Isaza Denunciar

0

Based on your example strings, as a pattern you could use 2 capture groups:

([^:\n]+):.*?\(max length=([^\s=()]+)\)

The pattern matches:

  • ([^:]+) Capture group 1, match 1+ times any character except for a : or newline
  • :.*? Match : and the rest of the line no greedy
  • \(max length= Match (max length=
    • ([^\s=()]+) Capture group 2, match 1+ times any character except for = ( )
  • \) Match )

Regex demo

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]}'`);
}

If you want to match only digits for the limit, you can also use \d+

([^:\n]+):.*?\(max length=(\d+)\)
about 4 years ago · Juan Pablo Isaza Denunciar

0

This is a bit gross. There might be a better way.

Part 1, extract the variable names from the template.

Part 2, split the template by those names to get the "rest of the template"

Part 3, convert "rest of template" fragments to regex compatible format. I probably missed a few things that need to be escaped

Part 4, join the template fragments back to a regex-compatible string, separated by (.*?) - which will capture the actual values of the variables

Part 5, run the constructed regex against the message, to extract variable values

Part 6, generate a return structure from the variable names and values

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);

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda