regex para corresponder a EOF

90

Eu tenho alguns dados parecidos com este

john, dave, chris
rick, sam, bob
joe, milt, paul

Estou usando este regex para combinar os nomes

/(\w.+?)(\r\n|\n|,)/

que trabalha para a maior parte, mas as extremidades de arquivo abruptamente após a última palavra que significa o último valor não termina em \r\n, \nou ,ele termina com EOF. Existe uma maneira de corresponder EOF em regex para que eu possa colocá-lo nesse segundo agrupamento?

Ryan
fonte
Você está tentando capturar todos os nomes em um grupo ou um grupo de captura por nome?
Andrew Hare
uma coisa a fazer quando tiver problemas com regex é tentar elementos de seu padrão isoladamente. se você estiver preocupado com o token no final, teste sua expressão sem ele.
akf
só queria adicionar um ótimo site de teste de regex: regexplanet.com/simple
northpole
@Sinan - eu concordo; mesclado
Marc Gravell

Respostas:

159

A resposta a esta pergunta \Zdemorou um pouco para eu descobrir, mas agora funciona. Observe que, inversamente, \Acorresponde ao início de toda a string (em oposição a ^e $correspondendo ao início de uma linha).

Ryan
fonte
5
Apenas um aviso se você estiver atrás de tal funcionalidade no netbeans para uma pesquisa de arquivos de projeto ao invés de uma pesquisa em arquivo , o seguinte se comportará de forma diferente ... (\s*)\?>(\s*)\Z... e depois de mais escavações aqui está o que funcionaria em uma pasta de projeto : (\s*)\?>(\s*)(\n*)(\W)\Z FYI: substitui todas as tags php de fechamento por quebras de linha no final do arquivo.
MediaVince
1
Acontece que \Atambém funciona no Visual Studio, localizar e substituir. Como sempre, use essas coisas com cuidado, mas isso me salvou de uma tonelada de problemas manuais, uma vez que eu estava feliz que realmente faria a coisa certa.
Steve Pettifer
Enquanto estou usando a Scannerclasse Java para ler um arquivo inteiro de uma vez; se eu usar \Zcomo delimitador, o caractere de nova linha final aparado. Quando alterei o delimitador para \z, o caractere de nova linha final foi preservado. Parece que a resposta de Martin Dorey também se aplica a Java.
mmdemirbas
24

EOF não é realmente um personagem. Se você tiver uma string de várias linhas, '$' corresponderá ao final da string e também ao final de uma linha.

Em Perl e seus irmãos, \Ae \Zcombine o início e o fim da string, ignorando totalmente as quebras de linha.

Extensões GNU para uso de regexes POSIX \` e \'para as mesmas coisas.

paxdiablo
fonte
17

No Visual Studio, você pode encontrar EOF assim: $(?![\r\n]) . Isso funciona se as terminações de linha são CR, CRLF ou apenas LF.

Como um bônus, você pode garantir que todos os seus arquivos de código tenham um marcador de nova linha final, como:

               Find What: (?<![\r\n])$(?![\r\n])
            Replace With: \r\n
 Use Regular Expressions: checked
Look at these file types: *.cs, *.cshtml, *.js

Como funciona:

Encontre qualquer extremidade de linha (uma correspondência de largura zero) que não seja precedida por CR ou LF e também não seja seguida por CR ou LF. Algum pensamento irá mostrar por que isso funciona!

Observe que você deve Substituir pelo caractere de final de linha desejado, seja CR, LF ou CRLF.

ErikE
fonte
Há um bug no Visual Studio 2019 em que substituir tudo por isso pode resultar na adição de duas novas linhas ao final do arquivo. Acho que tem algo a ver com a opção de inserir nova linha automaticamente ao salvar.
Stevoisiak
9

Compare o comportamento do \ Z sugerido por Ryan com \ z:

$ perl -we 'meu $ corpus = "olá \ n"; $ corpus = ~ s / \ Z / world / g; print (": $ corpus: \ n") '
:Olá Mundo
mundo:
$ perl -we 'meu $ corpus = "olá \ n"; $ corpus = ~ s / \ z / world / g; print (": $ corpus: \ n") '
:Olá
mundo:
$ 

perlre sez:

\ Z Match apenas no final da string, ou antes da nova linha no final
\ z Corresponde apenas no final da string

Uma tradução do caso de teste para Ruby (1.8.7, 1.9.2) se comporta da mesma forma.

Martin Dorey
fonte
2

Você realmente precisa capturar os separadores de linha? Caso contrário, esta regex deve ser tudo que você precisa:

/\w+/

Isso presumindo que todas as substrings que você deseja corresponder consistem inteiramente em caracteres de palavras, como em seu exemplo.

Alan Moore
fonte
2

Talvez tente $ (EOL / EOF) em vez de (\ r \ n | \ n)?

/\"(.+?)\".+?(\w.+?)$/
Marc Gravell
fonte
2

Recentemente, eu estava procurando algo assim, mas JavaScript.

Colocando isso aqui, para que qualquer pessoa com o mesmo problema possa se beneficiar

var matchEndOfInput = /$(?![\r\n])/gm;

Basicamente, isso corresponderia ao final da linha, que não é seguido por retorno de carro ou caracteres de nova linha. Em essência, isso é o mesmo, \Zmas para JavaScript.

Zlatin Zlatev
fonte
1

Assumindo que você está usando o modificador adequado forçando para tratar a string como um todo (não linha por linha - e se \ n funcionar para você, você está usando), basta adicionar outra alternativa - fim da string: (\ r \ n | \ n |, | $)

Nó da folha
fonte
0

/(\w.+?)(\r\n|\n|,|$)/

cubo
fonte
5
Provavelmente. Não me lembro mais :-)
cubo