Perl RegEx: значение "??" - PullRequest
       2

Perl RegEx: значение "??"

5 голосов
/ 17 апреля 2019

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

Я знаю, что делает это регулярное выражение (ищет проценты выше 80%), но я не помню его значение / принципы. Я вижу, что используется троичный оператор, а также последнее совпадение в круглых скобках, но я не знаю, например, значение ??:

qr/^(\d+)%$(??{$^N>= 80 ? '':'^'})/

Кто-нибудь может объяснить это регулярное выражение для меня?

Ответы [ 2 ]

10 голосов
/ 17 апреля 2019

Прежде чем я отвечу, я хотел бы отметить, что использование встроенной формы кода Perl (??...) может быть чревато ошибками, если вы не до конца понимаете, что это значит. Я написал регулярное выражение для Perl более двадцати лет, и моя естественная тенденция - всегда кодировать «вариант использования», подобный этому, в качестве фильтра к результату регулярного выражения, а не вставлять код Perl непосредственно в регулярное выражение. Вы были предупреждены.

Хорошо, давайте выберем это регулярное выражение:

^           # start of text

(           # begin capture group
  \d+         # one or more digits 0-9
)           # end of capture group

%           # literal percent sign character

$           # end of text

(??{        # start embedded perl code

  $^N >= 80   # if last closed match group($^N) is greater than or equal to 80
    ? ''        # then return empty pattern ('') 
    : '^'       # else return start of text (^) pattern

})          # end embedded perl code

, где $^N ссылается на значение самой последней пары закрытых совпадений, а предложение (??{ ... }) с нулевой шириной выполнит переносимый им код perl, преобразовав возвращаемое значение в новое регулярное выражение, которое будет добавлено к исходному. шаблон.

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

( Обратите внимание , что, добавив модификатор / x к вашему регулярному выражению Perl, вы можете вставлять комментарии непосредственно в шаблон, который также будет игнорировать встроенные пробелы. Я считаю, что это отличный способ документирования сложных регулярных выражений.)

7 голосов
/ 17 апреля 2019

$(??{code}) выполняет code, а затем подставляет результат в регулярное выражение.В этом случае $^N заменяется на то, что соответствует самой последней группе захвата, в данном случае (\d+).Регулярное выражение с этой подстановкой затем снова сопоставляется.

Так что, если строка начинается с числа, за которым следует %, ^(\d+)% соответствует этому.Затем он выполняет $^N >= 80 ? '' : '^', заменяя $^N числом.Если число не меньше 80, регулярное выражение становится ^(\d+)%, и все совпадение завершается успешно.Но если число меньше 80, оно становится ^(\d+)%^.Поскольку второе ^ не может совпадать в середине строки, регулярное выражение больше не совпадает.

Так что это регулярное выражение соответствует строкам, которые начинаются с процента не менее 80.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...