2011-12-28 22 views
6

La cadena puede ser como uno de los siguientes:¿Cómo puedo unir recursivamente un patrón usando expresiones regulares?

a(b,c) 
a(a(b,c),d) 
a(a(a(a(a(b,c),d),a(e,f)),g),h) 
etc 

Quiero coincidir con un número ilimitado de "un (x, y)". ¿Cómo puedo hacer eso usando Regex? Esto es lo que tengo:

\\w\\(((?:\\([a-zA-Z0-9]+\\))|(?:[a-zA-Z0-9]+)),((?:\\([a-zA-Z0-9]+\\))|(?:[a-zA-Z0-9]+))\\) 

Solo coincide con dos recursiones de "a (x, y)".

Respuesta

6

La biblioteca de expresiones regulares estándar de Java no es compatible con la recursión, por lo que no puede hacer coincidir las construcciones anidadas generales con ella.

Pero en sabores que hacen de soporte recursividad (Perl, PCRE, .NET, etc.) que puede utilizar expresiones como:

\w+(?:\((?R)(?:,(?R))*\))? 
+0

¿Estás seguro de que Python tiene esa característica? AFAIK, solo PHP, .NET y Perl son capaces de tal truco. –

+0

@BartKiers, correcto, Python no tiene '(? R)' y amigos, por alguna razón pensé que las versiones más nuevas de su motor de expresiones regulares lo soportaban. Se lo quitó de la lista. – Qtax

+0

No estoy muy familiarizado con Python, así que pensé que lo incluían en v3 (que realmente no he visto). –

0

El idioma que está describiendo no es regular language, por lo que no puede coincidir con una expresión regular. Mira en lexical analysis (es decir, utilizar un analizador)

+9

-1. Regex (en este contexto) no son regulares, y no lo han sido por más de 25 años. – Qtax

+4

Nitpick: el análisis léxico se basa en expresiones regulares; El análisis léxico convierte una secuencia de caracteres en una secuencia de símbolos según las reglas definidas por las expresiones regulares. Lo que soluciona el problema sobre el que pregunta el asker son los generadores de analizadores sintácticos. –

+3

@robert, (¿obviamente?) Qtax significaba regex en las herramientas de sistema operativo/API de programación. En ese contexto, Regex ha tenido la capacidad de hacer coincidir algo que se había emparejado anteriormente (agrupación y retro-referencia): haciéndolos capaces de hacer coincidir más que los lenguajes regulares. –

-1

Creo que busca algo como:

a (x, y) = [az] ([az], [az])

expresiones regulares = a (x, y) | a (regex | y) | a (x, regex)

No estoy seguro de cómo se puede hacer en un idioma.

+5

... esta no es una respuesta. –

0

2 opciones - 1) Uso Análisis léxico para hacer la comparación de patrones de sustitución & por su cuenta [O] 2) Si desea seguir con Regex y luego usar alguna programación de shell (o cualquier lenguaje de soporte) & llámelo desde Java.

0

¡También puede usar mi biblioteca de expresiones regulares https://github.com/florianingerl/com.florianingerl.util.regex, que admite expresiones regulares recursivas! La API es básicamente la misma que la de java.util.regex, solo las instrucciones de importación requeridas son diferentes, p.

Pattern p = Pattern.compile("(?<first>a\\((?<second>(?'first')|[a-zA-Z]),(?'second')\\))"); 
assert p.matcher("a(a(a(a(a(b,c),d),a(e,f)),g),h)").find(); 
Cuestiones relacionadas