javascript - RegExp no funciona en archivo HTML leído
Antes que nada, sé cómo suelen ser la mayoría de las preguntas sobre RegExp; y esta no es una de esas preguntas de "por favor, escribe mi código".
Mi confusión radica en el hecho de que mi RegExp funciona en regexr, y en las herramientas de desarrollo de Chrome al examinar el document.body.textContent, pero no en un archivo HTML después de haberlo leído en io.js.
io.js es la versión 1.5.1, funcionando en Windows 8
¿Por qué funcionaría en ambos lugares mencionados, pero no en io.js? ¿Acaso no estoy tomando en cuenta algo que io.js hace para leer archivos?
Mi RegExp debería coincidir con "@{each ___->___} texto y saltos de línea @{/each}" como lo hace en el enlace a continuación, pero en cambio, devuelve null
Aquí está lo que estoy tratando de usar: http://regexr.com/3aldk
Expresión regular :
/@\{each ([a-zA-Z0-9->.]*)\}([\s\S]*)@\{\/each}/gJS (Ejemplo):
fs.readFile('view.html', {encoding:'utf8'}, function(error, html) {
console.log(html.match(myRegExp)); // null
});
HTML :
<!doctype html>
<html>
<head>
<title>@{title}</title>
</head>
<body>
<h1>@{foo.bar}</h1>
<p>
Lorem ipsum dolor sit amet, @{foo.baz.hoo}
</p>
@{each people->person}
<div>
<b>@{person.name}:</b> @{person.age}
</div>
@{/each}
</body>
</html>
¿Me estoy perdiendo algo obvio, como un personaje, que está presente en el reverso, pero que nunca ha servido?
Respuesta #1
El problema aquí radica en la delgada línea entre especificación y implementaciones.
La especificación ECMAscript 5.1 establece que:
Un carácter
-puede tratarse de manera literal o puede denotar un rango. Se trata de manera literal si es el primer o último carácter de ClassRanges, el límite inicial o final de una especificación de rango, o si sigue inmediatamente a una especificación de rango.
Regular-Expressions.info señala que:
Los guiones en otras posiciones dentro de las clases de caracteres donde no pueden formar un rango pueden interpretarse como literales o como errores. Los sabores de expresiones regulares son bastante inconsistentes al respecto.
Conclusiones :
La manera segura de incluir un guion - signo menos en una clase de caracteres es mediante cualquiera de las siguientes:
- escapándolo (por ejemplo,
[a-zA-Z0-9\->.]) colocándolo como el primer carácter en la clase (por ejemplo,
[-.>a-zA-Z0-9])- excepción: en una clase negada va en segundo lugar, justo después de
^(ej.[^-.>a-zA-Z0-9])
- excepción: en una clase negada va en segundo lugar, justo después de
[a-zA-Z0-9.>-])Las pautas generales de codificación sugieren colocar sus rangos primero y terminar la clase de caracteres con el guion, esto evita ambigüedades y ayuda a la legibilidad.
Resumiendo, tu RegEx debería convertirse en:
/@\{each ([a-zA-Z0-9>.-]*)\}([\s\S]*)@\{\/each}/g
Como un consejo adicional:
también podrías reescribir [\s\S] (cualquier carácter de espacio en blanco o cualquier carácter que no sea espacio en blanco) como [^] (no nada)
lo que te dejaría con la siguiente expresión regular:
/@\{each ([a-zA-Z0-9>.-]*)\}([^]*)@\{\/each}/g
JavaScript ... trata
[^]como una clase de caracteres vacía negada que coincide con cualquier carácter individual. - fuente
