Superposición de coincidencias en Regex

Parece que no puedo encontrar una respuesta a este problema, y ​​me pregunto si existe. Ejemplo simplificado:

Considere una cadena “nnnn”, donde quiero encontrar todas las coincidencias de “nn”, pero también aquellas que se superponen entre sí. Entonces, la expresión regular proporcionaría las siguientes 3 coincidencias:

  1. nn nn
  2. n nn n
  3. nn nn

Me doy cuenta de que esto no es exactamente para lo que están diseñadas las expresiones regulares, pero caminar la secuencia y analizarlo manualmente parece una gran cantidad de código, considerando que en realidad las coincidencias deberían hacerse usando un patrón, no una cadena literal.

Una posible solución podría ser utilizar una mirada positiva detrás :

(?<=n)n 

Te daría la posición final de:

  1. * n *** n ** nn
  2. n * n *** n ** n
  3. nn * n *** n **

Como lo mencionó Timothy Khouri , una anticipación positiva es más intuitiva

Preferiría su proposición (?=nn)n la forma más simple:

 (n)(?=(n)) 

Eso haría referencia a la primera posición de las cadenas que desea y capturaría la segunda n en el grupo (2) .

Eso es así porque:

  • Cualquier expresión regular válida se puede usar dentro de la búsqueda anticipada.
  • Si contiene paréntesis de captura, las referencias hacia atrás se guardarán .

Entonces el grupo (1) y el grupo (2) capturarán lo que 'n' represente (incluso si es una expresión regular complicada).

Usar una búsqueda anticipada con un grupo de captura funciona a expensas de hacer que su expresión regular sea más lenta y más complicada. Una solución alternativa es decirle al método Regex.Match () dónde debe comenzar el siguiente bash de coincidencia. Prueba esto:

 Regex regexObj = new Regex("nn"); Match matchObj = regexObj.Match(subjectString); while (matchObj.Success) { matchObj = regexObj.Match(subjectString, matchObj.Index + 1); } 

AFAIK, no hay una forma pura de regex para hacer eso de una vez (es decir, devolver las tres capturas que solicite sin bucle).

Ahora, puede encontrar un patrón una vez y repetir la búsqueda comenzando con desplazamiento (posición encontrada + 1). Debe combinar el uso de expresiones regulares con un código simple.

[EDITAR] Genial, estoy desanimado cuando básicamente dije lo que Jan mostró …
[EDIT 2] Para ser claro: la respuesta de Jan es mejor. No es más preciso, pero ciertamente más detallado, merece ser elegido. Simplemente no entiendo por qué el mío está degradado, ya que todavía no veo nada incorrecto en él. No es gran cosa, solo molesto.