регулярное выражение для соответствия 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 используют \`и \'для тех же целей.

Paxdiablo
источник
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+/

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

Алан Мур
источник
2

Может быть, попробовать $ (EOL / EOF) вместо (\ r \ n | \ n)?

/\"(.+?)\".+?(\w.+?)$/
Марк Гравелл
источник
1

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

листовой узел
источник
0

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

куб
источник
5
Вероятно. Я уже не помню :-)
cube