Expressão regular para pular caracteres no grupo de captura

É possível pular alguns caracteres em um grupo de captura em expressões regulares? Eu estou usando regexes .NET, mas isso não importa.

Basicamente, o que estou procurando é:

[texto random] AB-123 [texto random]

e eu preciso capturar ‘AB123’, sem o hífen.

Eu sei que AB tem 2 ou 3 caracteres maiúsculos e 123 tem 2 ou 3 dígitos, mas essa não é a parte difícil. A parte difícil (pelo menos para mim) é pular o hífen.

Eu acho que eu poderia capturar os dois separadamente e depois concatená-los em código, mas eu gostaria de ter uma solução mais elegante, somente regex.

Alguma sugestão?

Resumindo: você não pode. Uma correspondência é sempre consecutiva, mesmo quando ela contém coisas como asserções de largura zero, não há nenhuma maneira de corresponder o próximo caractere se você quiser chegar a uma depois dela.

Não existe uma maneira de criar uma expressão de forma que o texto correspondido seja diferente do encontrado no texto de origem. Você precisará remover o hífen em uma etapa separada, combinando a primeira e a segunda partes individualmente e concatenando os dois grupos:

match = Regex.Match( text, "([AB]{2,3})-([0-9]{2,3})" ); matchedText = string.Format( "{0}{1}", match.Groups.Item(1).Value, match.Groups.Item(2).Value ); 

Ou removendo o hífen em uma etapa separada do processo de correspondência:

 match = Regex.Match( text, "[AB]{2,3}-[0-9]{2,3}" ); matchedText = match.Value.Replace( "-", "" ); 

Sua afirmação de que não é possível fazer isso sem o subgrupo + concatenando está correto.

Você também pode fazer como Jeff-Hillman e simplesmente tirar o (s) mau (s) personagem (s) após o fato.

Importante notar aqui tho, é você “não use regex para tudo”.

O Regex é projetado para soluções menos complicadas para problemas não-triviais, e você não deve usar “oh, vamos usar um regex” para tudo, e você não deve entrar no ambiente de pensar que pode resolver o problema regex de um passo.

Quando há um método trivial viável que funciona, por todos os meios, use-o.

Uma Idéia alternativa, se você precisar retornar várias correspondências em um corpo de código, procurará a regex baseada em “retorno de chamada” de seus idiomas, o que permite passar qualquer grupo correspondente a uma chamada de function que possa fazer uma substituição in-line. (Especialmente útil em fazer substituições regexp).

Não tenho certeza como isso funcionaria em .net, mas em php você faria algo como (código não exatamente)

  function strip_reverse( $a ) { $a = preg_replace("/-/", "", $a ); return reverse($a); } $b = preg_replace_callback( "/(AB[-]?cde)/" , 'strip_reverse' , "Hello World AB-cde" ; 

Você pode usar grupos de captura nesteds, como este:

 ((AB)-(123)) 

O primeiro grupo de captura é o AB-123 , o segundo é o AB e o terceiro é o 123 . Então tudo que você precisa fazer é juntar o segundo e terceiro grupo com um espaço.

Meio tarde, mas acho que percebi isso. Pelo menos uma maneira de fazer isso.

Eu usei lookahead positivo para parar no sinal # no meu texto. Eu não queria o espaço ou o sinal #, então eu tive que descobrir uma maneira de “pular” sobre eles. Então, quando fui forçado a combiná-los novamente, eu os joguei em um grupo de lixo que eu não planejava usar (como um balde) no código. Agora, meu ponteiro de lugar é uma posição de caractere além do sinal # (onde eu quero estar, ignorando o espaço e o sinal #). E agora eu apenas coincidir com o final do nome do arquivo no. e ignorar a extensão do arquivo.

 (?i)English\\(?[^ ]+) - (?.+(?= #))(?<garb1>..)(?<number>[^.]+)(?-i)</number></garb1> 

O nome do arquivo em que foi usado é

 F:\Downloads\Downloads\500 Comics CCC CBR English\Isukani - Great Girl #01.cbr