Mi entrada multilínea string:

123
 2345 a

ab_cd: xxxx
   123abc     456
:y

Lo que me gustaría obtener es la primera coincidencia de cada línea donde se ajusta el patrón [0-9a-z_]{1,100}, ignorando el espacio en blanco al principio y las líneas vacías.

Entonces mi resultado esperado sería:

123
2345
ab_cd
123abc

Mi patrón no parece funcionar:

$entries = string.match(/^(?:\s*)([a-z0-9_]{1,100})(?:.*)$/gm);    

El grupo que no captura parece ser ignorado. Yo obtengo:

[ "123", " 2345 a", " ab_cd: xxxx", "   123abc     456" ]

Solo :y se ignora correctamente. ¿Qué estoy haciendo mal aquí? Aunque he agregado esta etiqueta, supongo que no es un problema de JS ...

Editar : Estaría encantado de resolver el problema con el patrón regex, no con los medios JS.

1
robsch 10 may. 2016 a las 13:51

3 respuestas

La mejor respuesta

Puede usar

/^[ \t]*([0-9a-z_]{1,100})/gm

Y tome el valor en el Grupo 1.

Si necesita combinar también letras mayúsculas, simplemente use

/^[ \t]*(\w{1,100})/gm
         ^^

Vea la demostración de expresiones regulares

var re = /^[ \t]*(\w{1,100})/gm; 
var str = '123\n 2345 a\n\nab_cd: xxxx\n   123abc     456\n:y';
var res = [];
while ((m = re.exec(str)) !== null) {
    res.push(m[1]);
}
document.body.innerHTML = "<pre>" + JSON.stringify(res, 0, 4) + "</pre>";

Detalles del patrón : utiliza indicadores /gm: modificadores globales y multilínea para hacer coincidir todas las subcadenas que el patrón puede encontrar y hacer que ^ coincida con el inicio de las líneas.

  • ^ - inicio de una línea
  • [ \t]* - 0+ espacios o pestañas
  • ([0-9a-z_]{1,100}) - Grupo 1: 1 a 100 letras, dígitos o _. Si las mayúsculas también deben coincidir, use \w en su lugar.
1
Wiktor Stribiżew 10 may. 2016 a las 10:55

Tu expresión regular puede parecerse a algo como:

/^[\s]*([\da-z_]{1,100})/gm

Regex101 Demo


Explicación de expresiones regulares:

^ assert position at start of a line
[\s]* match a single character present in the list below
    Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
    \s match any white space character [\r\n\t\f ]
1st Capturing group ([0-9a-z_]{1,100})
    [0-9a-z_]{1,100} match a single character present in the list below
        Quantifier: {1,100} Between 1 and 100 times, as many times as possible, giving back as needed [greedy]
        0-9 a single character in the range between 0 and 9
        a-z a single character in the range between a and z (case sensitive)
        _ the literal character _
m modifier: multi-line. Causes ^ and $ to match the begin/end of each line (not only begin/end of string)
g modifier: global. All matches (don't return on first match)
0
Pedro Lobito 10 may. 2016 a las 11:01

Puedes hacerlo con la fórmula split-trim-join

var output = string.split("\n").map( function(val){
  return val.trim()
}).join("\n");

Más forma multiplataforma (cuidando también \r)

var output = string.replace(/\r\n/g,"\n").split("\n").map( function(val){
  return val.trim()
}).join("\n");
0
gurvinder372 10 may. 2016 a las 11:04