Sobreposição de correspondências no Regex

Eu não consigo encontrar uma resposta para este problema, e eu estou querendo saber se existe um. Exemplo simplificado:

Considere uma string “nnnn”, onde quero encontrar todas as correspondências de “nn” – mas também aquelas que se sobrepõem umas às outras. Portanto, o regex forneceria as seguintes 3 correspondências:

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

Eu percebo que isso não é exatamente o significado de regexes, mas andar a corda e analisá-la manualmente parece um monte de código, considerando que, na realidade, as correspondências teriam que ser feitas usando um padrão, não uma string literal.

    Uma possível solução poderia ser usar um olhar positivo para trás :

    (?< =n)n 

    Isso lhe daria a posição final de:

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

    Como mencionado por Timothy Khouri , uma visão positiva é mais intuitiva

    Eu preferiria a sua proposição (?=nn)n na forma mais simples:

     (n)(?=(n)) 

    Isso referenciaria a primeira posição das strings desejadas e capturaria o segundo n no grupo (2) .

    Isso é assim porque:

    • Qualquer expressão regular válida pode ser usada dentro do lookahead.
    • Se ele contiver parênteses de captura, as referências anteriores serão salvas .

    Então, group (1) e group (2) irão capturar o que 'n' representa (mesmo que seja um regex complicado).

    Usar um lookahead com um grupo de captura funciona, às custas de tornar seu regex mais lento e mais complicado. Uma solução alternativa é informar ao método Regex.Match () onde a próxima tentativa de correspondência deve começar. Tente isto:

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

    AFAIK, não existe uma forma pura de regex para fazer isso de uma só vez (isto é, retornar as três capturas que você solicita sem loop).

    Agora, você pode encontrar um padrão uma vez e fazer um loop na busca começando com offset (posição encontrada + 1). Deve combinar o uso regex com código simples.

    [EDIT] Ótimo, eu estou downvoted quando eu basicamente disse o que Jan mostrou …
    [EDIT 2] Para ser claro: a resposta de Jan é melhor. Não mais preciso, mas certamente mais detalhado, merece ser escolhido. Eu simplesmente não entendo porque o meu é downvoted, já que eu ainda não vejo nada incorreto nele. Não é grande coisa, apenas irritante.