2012-04-09 17 views
5

En la siguiente cadena de entrada:Orientación de expresiones regulares necesario para Javascript

{$foo}foo bar \\{$blah1}oh{$blah2} even more{$blah3} but not{$blarg}{$why_not_me} 

Estoy tratando de igualar todas las instancias de {$SOMETHING_HERE} que no están precedidos por una barra invertida sin escapar.

Ejemplo:

quiero que coincide {$SOMETHING} pero no \{$SOMETHING}.

Pero yo quiero que coincide \\{$SOMETHING}

intentos:

todos mis intentos hasta ahora coincidirá con lo que yo quiero, excepto para las etiquetas justo al lado de la otra como {$SOMETHING}{$SOMETHING_ELSE}

Aquí es lo que tengo actualmente:

var input = '{$foo}foo bar \\{$blah1}oh{$blah2} even more{$blah3} but not{$blarg}{$why_not_me}'; 
var results = input.match(/(?:[^\\]|^)\{\$[a-zA-Z_][a-zA-Z0-9_]*\}/g); 
console.log(results); 

Qué salidas:

["{$foo}", "h{$blah2}", "e{$blah3}", "t{$blarg}"] 

Meta

que quieren que sea:

["{$foo}", "{$blah2}", "{$blah3}", "{$blarg}", "{$why_not_me}"] 

Pregunta

Puede alguien me punto en la dirección correcta?

Respuesta

1

El problema aquí es que se necesita una búsqueda hacia atrás, que JavaScript regexs no son compatibles con

básicamente necesita "$ {} lo que sea si está precedido por una doble barra, pero no una sola barra", que es lo el lookbehind lo hace.

Puede imitar casos simples de lookbehinds, pero no está seguro si va a ayudar en este ejemplo. Darle una oportunidad: http://blog.stevenlevithan.com/archives/mimic-lookbehind-javascript

edición Por cierto, no creo que pueda hacer esto una 'manera estúpida', ya sea porque si tiene [^\\]\{ podrás combinar con cualquier carácter que no sea una barra invertida antes de la llave . Realmente necesitas el lookbehind para hacer esto limpiamente.

lo contrario, puede hacer

(\\*{\$[a-zA-Z_][a-zA-Z0-9_]*\}) 

A continuación, sólo contar el número de barras invertidas en las fichas resultantes.

+0

Soy consciente de que lo que necesito es un look-behind y que javascript no los admite. ¡Nunca antes había hecho un look falso pero verifico el enlace! – nathanjosiah

+0

@nathanjosiah He actualizado mi respuesta con más información. – Griffin

+0

¡Gracias por el artículo! ¡Justo lo que necesitaba! Publiqué mi solución como una respuesta. – nathanjosiah

0

Esto parece hacer lo que quiera:

var input = '{$foo}foo bar \\{$blah1}oh{$blah2} even more\\\\{$blah3} but not{$blarg}{$why_not_me}'; 

var results = []; 
input.replace(/(\\*)\{\$[a-z_][a-z0-9_]*\}/g, function($0,$1){ 
    $0 = $0.replace(/^\\\\/g,''); 
    var result = ($0.indexOf('\\') === 0 ? false : $0); 

    if(result) { 
     results.push(result); 
    } 
}) 

console.log(results); 

Lo que da:

["{$foo}", "{$blah2}", "{$blah3}", "{$blarg}", "{$why_not_me}"] 
1

Cuando todo lo demás falla, dividir, unir/reemplazar la basura fuera de ella.

Nota: la primera división/unión es en realidad la parte de limpieza. Eso mata \ {< *>}

Además, no contabilicé las cosas entre corchetes porque ya hay un código para eso.

var input = '{$foo}foo bar \\{$blah1}oh{$blah2} even more\\\\{$blah3} but not{$blarg}{$why_not_me}'; 

input.split(/(?:[^\\])\\\{[^\}]*\}/).join('').replace(/\}[^\{]*\{/g,'},{').split(/,/)); 
Cuestiones relacionadas