2012-08-13 10 views
8

El siguiente código evalúa 2 en lugar de 4:Contando partidos superpuestos con expresiones regulares en C#

Regex.Matches("020202020", "020").Count; 

Estoy adivinando la expresión regular empieza a buscar el partido desde el final del partido anterior. Hay alguna forma de prevenir esto. Tengo una serie de '0's y' 2's y estoy tratando de contar cuántas veces tengo tres '2's seguidos, cuatro' 2 seguidos, etc.

+0

su pregunta es engañoso. ¿Quieres unir '2'-s consecutivas o secuencias arbitrarias? – krlmlr

Respuesta

8

Esto devolverá 4 como se esperaba:

Regex.Matches("020202020", @"0(?=20)").Count; 

La anticipación coincide con20 sin consumiendo, por lo que el siguiente intento de coincidencia comienza en la posición siguiente al 0.Incluso se puede hacer toda la expresión regular como una búsqueda hacia delante:

Regex.Matches("020202020", @"(?=020)").Count; 

El motor de expresiones regulares choca de forma automática realiza un cambio de posición cada vez que se hace un partido de longitud cero. Por lo tanto, para encontrar todas las carreras de tres 2 's o cuatro 2' s, puede utilizar:

Regex.Matches("22222222", @"(?=222)").Count; // 6 

... y:

Regex.Matches("22222222", @"(?=2222)").Count; // 5 

EDIT: Mirando por encima de su pregunta de nuevo, se me ocurre que podría estar buscando 2 's intercalados con 0' s

Regex.Matches("020202020", @"(?=20202)").Count; // 2 

Si usted no sabe cuántos 0 's habrá, puede utilizar esto:

Regex.Matches("020202020", @"(?=20*20*2)").Count; // 2 

Y, por supuesto, se pueden utilizar cuantificadores para reducir la repetición en la expresión regular:

Regex.Matches("020202020", @"(?=2(?:0*2){2})").Count; // 2 
4

De hecho, una expresión regular continuará desde donde el último terminó Puede solucionarlo mediante el uso de patrones de anticipación. No soy un chico de .NET, pero prueba esto: "(?=020)." Traducción: "encuéntrame un solo carácter, donde este personaje y los próximos dos caracteres son 020". El truco es que la coincidencia es de solo un personaje de ancho, no tres, por lo que obtendrá todas las coincidencias en la cadena, incluso si se superponen.

(también se puede escribir como "0(?=20)", pero eso es menos clara para los seres humanos, al menos: p)

0

Suponiendo que usted es de hecho buscando secuencias de 2 -s consecutivos, no hay otra opción sin usar los símbolos de anticipación en absoluto. (Esto no funcionaría para las secuencias arbitrarias en el que buscar patrones de 0 y 2.)

Enumerar todas las apariciones de secuencias no superpuestas de tres o más 2 -s (¿cómo?) Y luego deducir el número de subsecuencias más cortas .

Por ejemplo, si encuentra una secuencia de seis 2 -s consecutivos y una de cinco 2 -s consecutivas, entonces sabe que debe tener (6-3 + 1) + (5-3 + 1) = ? secuencias de tres 2 -s consecutivos (potencialmente superpuestos), y así sucesivamente:

0002222220000002222200 
    222 
    222 
    222 
     222 
       222 
       222 
       222 

Para las grandes cadenas, esto debería ser un poco más rápido que el uso de los símbolos de anticipación.

-4

Debido a que la fuente contiene dos patrones "020" con los que su patrón de expresiones regulares coincide. Intente cambiar su fuente a este:

Regex.Matches("020202020", "02").Count; 

Ahora coincidirá con 02's en una fila y obtendrá cuatro esta vez.

+1

Devolverá el mismo resultado para '" 029029029029 "' también. Buscar '" 02 "' no es equivalente a buscar '" 020 "'. – Amadan

Cuestiones relacionadas