Sobrepostas partidas em Regex
Pergunta
Eu não consigo encontrar uma resposta para este problema, e eu estou querendo saber se houver. Exemplo simplificado:
Considere uma string "nnnn", onde eu quero encontrar todos os jogos de "nn" - mas também aqueles que se sobrepõem uns com os outros. Assim, a regex iria fornecer os seguintes 3 jogos:
- nn nn
- n nn n
- nn nn
Sei que isso não é exatamente o que expressões regulares são destinados a, mas andando a corda e analisar isto parece manualmente como uma enorme quantidade de código, considerando que, na realidade, os jogos teriam de ser feito usando um padrão, não uma string literal .
Solução
Uma possível solução poderia ser usar um href="http://www.regular-expressions.info/lookaround.html" rel="nofollow olhar positiva por trás :
(?<=n)n
Seria dar-lhe a posição final:
- * n *** n nn **
- n * n *** n ** n
- nn * n *** n **
Como mencionada por Timothy Khouri , um antecipação positiva é mais intuitivo
Eu preferiria seu (?=nn)n
proposição a forma mais simples:
(n)(?=(n))
Isso faria referência a primeira posição das cordas que você quer e iria capturar o segundo n no grupo (2) .
Isso é assim porque:
- Qualquer expressão regular válida pode ser usado dentro da visão antecipada.
- Se ele contém parênteses captura, o backreferences será salvo .
grupo Então (1) e grupo (2) irá capturar tudo o que 'n' representa (mesmo que seja um regex complicado).
Outras dicas
Usando um lookahead com um grupo de captura funciona, à custa de fazer o seu regex mais lento e mais complicado. Uma solução alternativa é contar o método Regex.Match (), onde a próxima tentativa jogo 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 há nenhuma maneira regex puro para fazer isso de uma vez (ie. Retornando os três capturas você solicitar, sem loop).
Agora, você pode encontrar um padrão uma vez, e laço na pesquisa 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 que Jan mostrado ...
[EDIT 2] Para ser claro: a resposta de Janeiro é melhor. Não mais preciso, mas certamente mais detalhado, que merece ser escolhido. Eu só não entendo por que o meu é downvoted, já que eu ainda vejo nada de errado nisso. Não é grande coisa, apenas irritante.