2008-10-27 21 views
29

Estoy desarrollando un algoritmo para analizar un número de una serie de cadenas cortas. Estas cadenas son algo regulares, pero hay algunas formas generales diferentes y varias excepciones. Estoy intentando crear un conjunto de expresiones regulares que manejarán las diversas formas y excepciones; Los aplicaré uno tras otro para ver si obtengo una coincidencia.Coincidencia de una subcadena opcional en una expresión regular

Una de estas formas es algo como esto:

X (Y) Z 

Dónde:

  • X es un número que quiero capturar.
  • Z es texto estático, predefinido. es básicamente cómo determino si esta forma particular es aplicable o no.
  • Y es una cadena de longitud y contenido desconocidos, rodeada de paréntesis.

También: Y es opcional; que no siempre aparece en una cadena con Z y X. Por lo tanto, quiero ser capaz de extraer los números de todas estas cadenas:

  • 10 Z
  • 20 (foo) Z
  • 30 (bar) Z

en este momento, tengo una expresión regular que capturará la primera:

([0-9]+) +Z 

Mi problema es que no sé cómo construir una expresión regular que coincidirá con una serie de caracteres si y solo si están entre paréntesis. ¿Se puede hacer esto en una sola expresión regular?

Respuesta

46
(\d+)\s+(\(.*?\))?\s?Z 

Tenga en cuenta el paréntesis escapado, y? (cero o una vez) cuantificadores. Cualquiera de los grupos que no desea capturar puede ser (?: Grupos sin captura).

Acepto los espacios. \ s es una mejor opción allí. También cambié el cuantificador para asegurar que haya dígitos al principio. En cuanto a las nuevas líneas, eso dependería del contexto: si el archivo se analiza línea por línea, no será un problema. Otra opción es anclar el inicio y el final de la línea (agregue un^al frente y un $ al final).

+0

Los espacios son estáticos. Reemplazarlos con \ s + –

+0

o colocar uno de ellos dentro de()? –

+0

Tenga en cuenta que si la expresión regular captura \ n con. o si hay varias instancias en una línea, esto debería ser no codicioso: (\ d *) (\ (. *? \))? Z – eyelidlessness

2

Prueba esto:

X (\(Y\))? Z 
7

usted puede hacer esto:

([0-9]+) (\([^)]+\))? Z 

Esto no funcionará con parens anidados para Y, sin embargo. El anidamiento requiere recursión que ya no es estrictamente regular (pero sin contexto). Los motores regexp modernos aún pueden manejarlo, aunque con algunas dificultades (referencias).

+1

Afortunadamente, no creo que deba manejar parens anidados. –

14

Esto se debe trabajar;

^\d+\s?(\([^\)]+\)\s?)?Z$ 

no lo he probado sin embargo, pero te voy a dar la descomposición, por lo que si hay cualquier error dejaron que debe ser bastante sencillo encontrar:

En primer lugar el principio:

^ = beginning of string 
\d+ = one or more decimal characters 
\s? = one optional whitespace 

Entonces esta parte:

(\([^\)]+\)\s?)? 

es en realidad:

(.............)? 

que hace que el siguiente contenido opcional, sólo si existe plenamente

\([^\)]+\)\s? 

\(= an opening bracket 
[^\)]+ = a series of at least one character that is not a closing bracket 
\) = followed by a closing bracket 
\s? = followed by one optional whitespace 

Y al final se compone de

Z$ 

Dónde

Z = your constant string 
$ = the end of the string 
Cuestiones relacionadas