В чем разница между этими двумя регулярными выражениями? (Понимание? Квантор)
В книге 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*
может соответствовать нескольким строкам до первого непробельного символа.
Ваше модифицированное окончательное регулярное выражение требует точки с запятой. Исходное регулярное выражение будет соответствовать строкам, которые являются только пробелами.
Поскольку целью (если я правильно понимаю) является игнорирование строк, сопоставленных с этим регулярным выражением (как - якобы - строки комментариев), имеет смысл также игнорировать пустые строки.