В чем разница между этими двумя регулярными выражениями? (Понимание? Квантор)

В книге Eloquent JavaScript, глава 9: Регулярные выражения в разделе "Анализ файла INI", есть пример, который включает в себя регулярное выражение, которое я вообще не улавливаю. Автор пытается разобрать следующий контент:

searchengine=http://www.google.com/search?q=$1
spitefulness=9.7

; comments are preceded by a semicolon...
; each section concerns an individual enemy
[larry]
fullname=Larry Doe
type=kindergarten bully
website=http://www.geocities.com/CapeCanaveral/11451

[gargamel]
fullname=Gargamel
type=evil sorcerer
outputdir=/home/marijn/enemies/gargamel

В правилах для этого формата говорится, что

Пустые строки и строки, начинающиеся с точки с запятой, игнорируются.

Код, который анализирует это содержимое, проходит через каждую строку в файле. Для обработки комментариев он включает это выражение

^\s*(;.*)?

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

символы пробела, включая пробел, табуляцию, перевод формы, перевод строки и другие пробелы Юникода

( источник), пока не появится точка с запятой ; а затем последовательность "любой отдельный символ, кроме разделителей строк: \n, \r, \u2028 или \ u2029.". Все это ограничено до {0,1} появлений.

Я не понимаю точку квантификатора ? Вот. Я не могу найти ( regex101) ни одного случая, когда ограничение количества совпадающих строк может быть проблемой. Почему это выражение отличается от этого другого:

^\s*(;.*)

Заранее спасибо.

2 ответа

Решение

^\s*(;.*) требует ;, это не может соответствовать пустой строке.

^\s*(;.*)? может соответствовать пустой строке, это не требует ;,

Общая часть ^\s* - начало строки (или строки), а затем ноль или более пробелов.

Тогда 1) (;.*) соответствует ; (1 экземпляр обязательно), а затем ноль или более символов, кроме новой строки, и 2) (;.*)? соответствует необязательной последовательности ((...)? является необязательной группой, так как ? является квантификатором, соответствующим одному или нулю вхождений квантифицированного атома, в то время как атом может быть символом, классом символов, группой) ; сопровождаемый 0+ символами кроме новой строки.

Также обратите внимание, что \s соответствует символам LF и CR, и это означает, что (если модификатор MULTILINE включен, а вход представляет собой текст, содержащий несколько строк), регулярное выражение ^\s* может соответствовать нескольким строкам до первого непробельного символа.

Ваше модифицированное окончательное регулярное выражение требует точки с запятой. Исходное регулярное выражение будет соответствовать строкам, которые являются только пробелами.

Поскольку целью (если я правильно понимаю) является игнорирование строк, сопоставленных с этим регулярным выражением (как - якобы - строки комментариев), имеет смысл также игнорировать пустые строки.

Другие вопросы по тегам