Estou com dificuldade para encontrar um bom recurso que explique como usar Grupos de Captura Nomeados em C #. Este é o código que eu tenho até agora:
string page = Encoding.ASCII.GetString(bytePage);
Regex qariRegex = new Regex("<td><a href=\"(?<link>.*?)\">(?<name>.*?)</a></td>");
MatchCollection mc = qariRegex.Matches(page);
CaptureCollection cc = mc[0].Captures;
MessageBox.Show(cc[0].ToString());
No entanto, isso sempre mostra apenas a linha completa:
<td><a href="/path/to/file">Name of File</a></td>
Eu experimentei vários outros "métodos" que encontrei em vários sites, mas continuo obtendo o mesmo resultado.
Como posso acessar os grupos de captura nomeados especificados na minha regex?
<>
será interrompido. Você pode usar(?'link'.*)
neste caso. Não inteiramente relevante para esta pergunta, mas eu aterrei aqui de uma pesquisa no Google de ".net chamados grupos de captura" Então, eu tenho certeza que outras pessoas são bem ...<>
isso não será interrompido. Consegui usar amyRegex.GetGroupNames()
coleção como os nomes dos elementos XML.Respostas:
Use a coleção de grupo do objeto Match, indexando-o com o nome do grupo de captura, por exemplo
fonte
var m
, pois isso seria umobject
.Você especifica a sequência do grupo de captura nomeado passando-a para o indexador da
Groups
propriedade de umMatch
objeto resultante .Aqui está um pequeno exemplo:
fonte
O exemplo de código a seguir corresponderá ao padrão mesmo no caso de caracteres de espaço no meio. ou seja:
assim como:
O método retorna verdadeiro ou falso, dependendo se a sequência htmlTd de entrada corresponde ao padrão ou não. Se corresponder, os parâmetros de saída conterão o link e o nome, respectivamente.
Eu testei isso e funciona corretamente.
fonte
${1}
manter as coisas ainda mais simples.Além disso, se alguém tiver um caso de uso em que ele precisa de nomes de grupos antes de executar a pesquisa no objeto Regex, ele poderá usar:
fonte
Essas respostas melhoram a resposta de Rashmi Pandit , que é um pouco melhor que as demais, porque parece resolver completamente o problema exato detalhado na pergunta.
A parte ruim é que é ineficiente e não usa a opção IgnoreCase de forma consistente.
Parte ineficiente é porque o regex pode ser caro para construir e executar, e nessa resposta ele poderia ter sido construído apenas uma vez (chamar
Regex.IsMatch
estava apenas construindo o regex novamente nos bastidores). EMatch
método poderia ter sido chamado apenas uma vez e armazenados em uma variável e, em seguida,link
ename
deve chamarResult
a partir dessa variável.E a opção IgnoreCase foi usada apenas na
Match
parte, mas não naRegex.IsMatch
parte.Também mudei a definição Regex para fora do método, a fim de construí-la apenas uma vez (acho que é a abordagem sensata se estivermos armazenando esse assembly com a
RegexOptions.Compiled
opção).fonte