regex pour correspondre à EOF

J'ai des données qui ressemblent à ça

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

J'utilise cette expression rationnelle pour correspondre aux noms

/(w.+?)(rn|n|,)/

Qui fonctionne pour la plupart, mais le fichier se termine brusquement après le dernier mot, ce qui signifie que la dernière valeur ne se termine pas rn, n ou {[4] } il se termine par EOF. Existe-t-il un moyen de faire correspondre EOF dans regex afin que je puisse le mettre dans ce deuxième groupe?

65
demandé sur Alan Moore 2009-07-23 16:01:30

9 réponses

La réponse à cette question est \Z m'a pris un certain temps pour le comprendre, mais cela fonctionne maintenant. Notez qu'à l'inverse, \A correspond au début de l'ensemble de la chaîne (par opposition à ^ et $ correspondant au début d'une ligne).

128
répondu Ryan 2012-11-19 18:02:00

EOF n'est pas réellement un personnage. Si vous avez un multi-ligne de chaîne, puis '$' correspondra à la fin de la chaîne ainsi que la fin d'une ligne.

Dans Perl et ses frères, \A et \Z correspondent au début et à la fin de la chaîne, ignorant totalement les sauts de ligne.

Les extensions GNU des expressions rationnelles POSIX utilisent \` et \' pour les mêmes choses.

19
répondu paxdiablo 2012-11-19 18:04:38

Dans Visual Studio, vous pouvez trouver EOF comme ceci: $(?![\r\n]). Cela fonctionne si vos fins de ligne sont CR, CRLF ou simplement LF.

En prime, vous pouvez vous assurer que tous vos fichiers de code ont un marqueur de nouvelle ligne final comme ceci:

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

Comment cela fonctionne:

Trouve toute fin de ligne (une correspondance de largeur nulle) qui n'est pas précédée par CR ou LF, et qui n'est pas non plus suivie par CR ou LF. Une certaine pensée vous montrera pourquoi cela fonctionne!

Notez que vous devez remplacer par votre caractère de fin de ligne souhaité, être il CR, LF ou CRLF.

10
répondu ErikE 2017-06-26 18:07:10

Contraste le comportement de \ Z suggéré par Ryan avec \z:

$ perl -we 'my $corpus = "hello\n"; $corpus =~ s/\Z/world/g; print(":$corpus:\n")'
:helloworld
world:
$ perl -we 'my $corpus = "hello\n"; $corpus =~ s/\z/world/g; print(":$corpus:\n")'
:hello
world:
$ 

Perlre sez:

\Z  Match only at end of string, or before newline at the end
\z  Match only at end of string

Une traduction du cas de test en Ruby (1.8.7, 1.9.2) se comporte de la même manière.

8
répondu Martin Dorey 2012-11-30 18:54:12

Devez-vous vraiment capturer les séparateurs de ligne? Sinon, cette regex devrait être tout ce dont vous avez besoin:

/\w+/

Cela suppose que toutes les sous-chaînes que vous voulez faire correspondre sont entièrement constituées de caractères word, comme dans votre exemple.

2
répondu Alan Moore 2009-07-23 12:33:21

Peut-être essayer $ (EOL/EOF) au lieu de (\r\n / \n)?

/\"(.+?)\".+?(\w.+?)$/
2
répondu Marc Gravell 2009-07-23 13:34:00

En supposant que vous utilisez un modificateur approprié pour traiter la chaîne dans son ensemble (Pas ligne par ligne-et si \n fonctionne pour vous, vous l'utilisez), ajoutez simplement une autre fin alternative de la chaîne: (\r\n|\n|,|$)

1
répondu leafnode 2009-07-23 12:04:27

Récemment, je cherchais quelque chose comme ça, mais pour JavaScript.

Mettre ceci ici, afin que toute personne ayant le même problème puisse en bénéficier

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

Fondamentalement, cela correspondrait à la fin de la ligne, qui n'est pas suivie par un retour chariot ou de nouveaux caractères de ligne. En substance, c'est la même chose que \Z mais pour JavaScript.

1
répondu Zlatin Zlatev 2017-11-20 13:29:50

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

0
répondu cube 2009-07-23 12:04:44