¿Por qué esta expresión regular de JavaScript no funciona?

Resuelto J4N asked hace 13 años • 1 respuestas

Estoy haciendo un pequeño método de JavaScript, que recibe una lista de puntos y tengo que leer esos puntos para crear un polígono en un mapa de Google.

Recibo esos puntos en el formulario:

(lat, largo), (lat, largo), (lat, largo)

Entonces hice la siguiente expresión regular:

\(\s*([0-9.-]+)\s*,\s([0-9.-]+)\s*\)

Lo probé con RegexPal y los datos exactos que recibo:

(25.774252, -80.190262),(18.466465, -66.118292),(32.321384, -64.75737),(25.774252, -80.190262)

y funciona, entonces, ¿por qué cuando tengo este código en mi javascript, recibo un valor nulo en el resultado?

var polygons="(25.774252, -80.190262),(18.466465, -66.118292),(32.321384, -64.75737),(25.774252, -80.190262)";
var reg = new RegExp("/\(\s*([0-9.-]+)\s*,\s([0-9.-]+)\s*\)/g");
var result = polygons.match(reg);

No tengo ningún error de JavaScript al ejecutar (con el modo de depuración de Google Chrome). Este código está alojado en una función de JavaScript que se encuentra en un archivo JS incluido. Este método se llama en el método OnLoad.

He buscado mucho, pero no encuentro por qué esto no funciona. ¡Muchas gracias!

J4N avatar Sep 15 '11 15:09 J4N
Aceptado

Utilice un literal de expresión regular [MDN] :

var reg = /\(\s*([0-9.-]+)\s*,\s([0-9.-]+)\s*\)/g;

Estás cometiendo dos errores cuando usas RegExp [MDN] :

  • Los "delimitadores" /no deben formar parte de la expresión.
  • Si define una expresión como cadena, debe escapar de la barra invertida, porque es el carácter de escape en las cadenas.

Además, los modificadores se pasan como segundo argumento de la función.

Entonces, si quisieras usar RegExp(lo cual no es necesario en este caso), el equivalente sería:

var reg = new RegExp("\\(\\s*([0-9.-]+)\\s*,\\s([0-9.-]+)\\s*\\)", "g");

(y creo que ahora entiendes por qué los literales de expresiones regulares son más convenientes)


Siempre me resulta útil copiar y pegar una RegExpexpresión en la consola y ver su resultado. Tomando su expresión original, obtenemos:

/(s*([0-9.-]+)s*,s([0-9.-]+)s*)/g

lo que significa que las expresiones intentan coincidir y /, literalmente, los pares todavía se tratan como caracteres especiales.sg()


Actualización: .match() devuelve una matriz:

["(25.774252, -80.190262)", "(18.466465, -66.118292)", ... ]

lo cual no parece ser muy útil.

Tienes que usar .exec() [MDN] para extraer los números:

["(25.774252, -80.190262)", "25.774252", "-80.190262"]

Esto debe llamarse repetidamente hasta que se procesen todas las cadenas.

Ejemplo:

var reg = /\(\s*([0-9.-]+)\s*,\s([0-9.-]+)\s*\)/g;
var result, points = [];

while((result = reg.exec(polygons)) !== null) {
    points.push([+result[1], +result[2]]);
}

Esto crea una matriz de matrices y el signo unario más ( +) convertirá las cadenas en números:

[
    [25.774252, -80.190262], 
    [18.466465, -66.118292], 
    ...
]

Por supuesto, si desea que los valores sean cadenas y no números, puede omitir el archivo +.

Felix Kling avatar Sep 15 '2011 08:09 Felix Kling