Probablemente sea más fácil hacer esto con un analizador simple. Pero usted can do this con.NET regex usando balancing groups y dándose cuenta de que si los corchetes se eliminan de la cadena, siempre tendrá una cadena que coincida con una expresión simple como ^\d+(?:\s+(?:AND|OR)\s+\d+)*\z
.
Así que todo lo que tiene que hacer es usar grupos de equilibrio para asegurarse de que los soportes estén equilibrados (y estén en el lugar correcto en la forma correcta).
Reescribiendo la expresión anterior un poco: (. (?x)
hace que el motor de expresiones regulares ignorar todos los espacios en blanco y los comentarios en el patrón, por lo que se puede hacer más legible)
(?x)^
OPENING
\d+
CLOSING
(?:
\s+(?:AND|OR)\s+
OPENING
\d+
CLOSING
)*
BALANCED
\z
Dónde OPENING
coincide con cualquier número (0 incluido) de soportes de apertura:
\s* (?: (?<open> \() \s*)*
CLOSING
coincide con cualquier número de tramos de cierre también debe asegurarse de que el grupo de equilibrado está equilibrado:
\s* (?: (?<-open> \)) \s*)*
y BALANCED
realiza una comprobación de equilibrio, fallando si hay soportes más abiertas cierran:
(?(open)(?!))
Dar la expresión:
(?x)^
\s* (?: (?<open> \() \s*)*
\d+
\s* (?: (?<-open> \)) \s*)*
(?:
\s+(?:AND|OR)\s+
\s* (?: (?<open> \() \s*)*
\d+
\s* (?: (?<-open> \)) \s*)*
)*
(?(open)(?!))
\z
Si no desea permitir espacios aleatorios, elimine cada \s*
.
Ejemplo
Ver demostración en IdeOne. Salida:
matched: '2'
matched: '1 AND 2'
matched: '12 OR 234'
matched: '(1) AND (2)'
matched: '(((1)) AND (2))'
matched: '1 AND 2 AND 3'
matched: '1 AND (2 OR (3 AND 4))'
matched: '1 AND (2 OR 3) AND 4'
matched: ' (1 AND (2 OR (3 AND 4) )'
matched: '((1 AND 7) OR 6) AND ((2 AND 5) OR (3 AND 4))'
matched: '(1)'
matched: '(((1)))'
failed: '1 2'
failed: '1(2)'
failed: '(1)(2)'
failed: 'AND'
failed: '1 AND'
failed: '(1 AND 2'
failed: '1 AND 2)'
failed: '1 (AND) 2'
failed: '(1 AND 2))'
failed: '(1) AND 2)'
failed: '(1)() AND (2)'
failed: '((1 AND 7) OR 6) AND (2 AND 5) OR (3 AND 4))'
failed: '((1 AND 7) OR 6) AND ((2 AND 5 OR (3 AND 4))'
failed: ''
¿también es posible tener esta combinación? '4 AND 5 (3 O 5) O (4 Y 6)' u etc .. –
@John Woo No ... Después de los primeros 5, no hay operador. Pero si te refieres a una expresión larga con muchas combinaciones, entonces sí. –
El emparejamiento de llaves es el ejemplo canónico de algo que un lenguaje normal no puede hacer. – harold