регулярное выражение для соответствия EOF


92

У меня есть данные, которые выглядят так

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

Я использую это регулярное выражение для сопоставления имен

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

который работает по большей части, но файл заканчивается внезапно после последнего слова, что означает, что последнее значение не заканчивается \r\n, \nили ,оно заканчивается EOF. Есть ли способ сопоставить EOF в регулярном выражении, чтобы я мог исправить это во второй группировке?


Вы пытаетесь захватить все имена в одной группе или одну группу захвата для каждого имени?
Эндрю Хэйр

при возникновении проблем с регулярным выражением нужно попробовать отдельные элементы шаблона. если вас беспокоит токен в конце, проверьте свое выражение без него.
akf

просто хотел добавить отличный сайт тестирования регулярных выражений: regexplanet.com/simple
northpole


@Sinan - согласен; объединено
Marc Gravell

Ответы:


163

\ZМне потребовалось некоторое время, чтобы понять ответ на этот вопрос , но теперь он работает. Обратите внимание , что , наоборот, \Aспички начала всей строки (в отличие от ^и $соответствий начала одной линии).


5
Просто предупреждаем, если вам нужна такая функциональность в netbeans для поиска файлов проекта, в отличие от поиска в файлах , следующее будет вести себя по-другому ... (\s*)\?>(\s*)\Z... и после еще нескольких копаний вот что будет работать с папкой проекта : (\s*)\?>(\s*)(\n*)(\W)\Z FYI: это заменить все закрывающие теги php на разрыв строки в конце файла.
MediaVince

1
Оказывается, \Aтакже работает поиск и замена Visual Studio. Как всегда, используйте такие вещи с осторожностью, но это избавило меня от множества ручных манипуляций, когда я был счастлив, что действительно все будет правильно.
Стив Петтифер,

Хотя я использую Scannerкласс Java для чтения всего файла сразу; если я использую в \Zкачестве разделителя, завершающий символ новой строки обрезается. Когда я изменил разделитель на \z, конечный символ новой строки сохранился. Кажется, что ответ Мартина Дори также относится к Java.
mmdemirbas 06

24

EOF на самом деле не персонаж. Если у вас многострочная строка, то '$' будет соответствовать как концу строки, так и концу строки.

В Perl и его собратьях \Aи \Zсопоставлять начало и конец строки, полностью игнорируя перенос строки.

Расширения GNU для регулярных выражений POSIX используют \`и \'для тех же целей.


18

В Visual Studio, вы можете найти EOF нравится так: $(?![\r\n]). Это работает независимо от того, заканчиваются ли ваши строки CR, CRLF или просто LF.

В качестве бонуса вы можете убедиться, что все ваши файлы кода имеют последний маркер новой строки, например:

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

Как это работает:

Найдите любой конец строки (совпадение нулевой ширины), которому не предшествуют CR или LF, а также не следует CR или LF. Некоторые мысли покажут вам, почему это работает!

Обратите внимание, что вы должны заменить желаемым символом окончания строки, будь то CR, LF или CRLF.


В Visual Studio 2019 есть ошибка, из-за которой замена всего этого может привести к добавлению двух символов новой строки в конец файла. Я думаю, это как-то связано с опцией автоматической вставки новой строки при сохранении.
Stevoisiak

10

Сравните поведение предложенного Райаном \ Z с \ z:

$ perl -we 'мой $ corpus = "привет \ п"; $ corpus = ~ s / \ Z / world / g; print (": $ corpus: \ n") '
:Привет, мир
Мир:
$ perl -we 'мой $ corpus = "привет \ п"; $ corpus = ~ s / \ z / world / g; print (": $ corpus: \ n") '
:Здравствуйте
Мир:
$ 

perlre sez:

\ Z Соответствует только в конце строки или перед новой строкой в ​​конце
\ z Соответствует только концу строки

Перевод тестового примера на Ruby (1.8.7, 1.9.2) ведет себя так же.


4

Недавно искал что-то подобное, но для JavaScript.

Поместите это здесь, чтобы любой, у кого возникла такая же проблема, мог получить пользу

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

Обычно это соответствует концу строки, за которым не следует возврат каретки или символы новой строки. По сути, это то же самое, что и \Zдля JavaScript.


2

Неужели нужно захватывать разделители строк? Если нет, то это регулярное выражение должно быть всем, что вам нужно:

/\w+/

Предполагается, что все подстроки, которые вы хотите сопоставить, полностью состоят из словесных символов, как в вашем примере.



1

Предполагая, что вы используете правильный модификатор, заставляющий обрабатывать строку в целом (а не построчно - и если \ n работает для вас, вы его используете), просто добавьте другую альтернативу - конец строки: (\ r \ n | \ п |, | $)


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.