st
может быть представлен в виде 1-символьной стилистической лигатуры как st
или ſt
, поэтому его длина может быть 2 или 1.
Быстрый поиск полного perlсписок из 2 → 1-символьных лигатур с использованием команды bash:
$ perl -e 'print $^V'
v5.26.2
$ for lig in {a..z}{a..z}; do \
perl -e 'print if /(?<!'$lig')x/i' 2>/dev/null || echo $lig; done
ff fi fl ss st
Они соответственно представляют ff
, fi
, fl
, ß
и st
/ ſt
лигатуры.
(ſt
представляет ſt
с использованием устаревшего символа long s ; соответствует st
и , а не соответствует ft
.)
Perl также поддерживает оставшиеся стилистические лигатуры, ffi
и ffl
для ffi
и ffl
, хотя это не заслуживает внимания в этом контексте, поскольку у lookbehind уже есть проблемы с ff
и fi
/ fl
отдельно.
Будущие выпуски Perl могут включать более стилистические лигатуры, хотя все, что остается, зависит от шрифта (например, Linux Libertine имеет стилистические лигатуры для ct
и ch
) или стилистически (например, голландский ij
для ij
или устаревший испанский ꝇ
для ll
).Кажется неуместным использовать этот способ для лигатур, которые не являются полностью взаимозаменяемыми (никто не принял бы dœs
для does
), хотя существуют и другие сценарии, например, включение ß
благодаря его заглавной формебудучи SS
.
Perl 5.16.3 (и аналогичные старые версии) только натыкаются на ss
(для ß
) и не в состоянии расширить другие лигатуры в вид сзади (они имеют фиксированную ширину)и не будет совпадать).Я не искал исправления, чтобы указать, какие именно версии подвержены уязвимости.
В Perl 5.14 появилась поддержка лигатуры, поэтому в более ранних версиях этой проблемы не было.
Временные решения
Обходные пути для /(?<!August)x/i
(только первый будет корректно избегать August
):
/(?<!Augus[t])(?<!Augu(?=st).)x/i
(абсолютно всеобъемлющий) /(?<!Augu(?aa:st))x/i
(только st
ввнешний вид "ASCII-безопасный" ²) /(?<!(?aa)August)x/i
(весь внешний вид "ASCII-безопасный" ²) /(?<!August)x/iaa
(все регулярное выражение "ASCII-безопасный"²) /(?<!Augus[t])x/i
(прерывает поиск лигатуры ¹) /(?<!Augus.)x/i
(немного отличается, соответствует больше) /(?<!Augu(?-i:st))x/i
(с учетом регистра st
в заднем плане, не будет соответствовать AugusTx
)
Эта игрушка с удалением нечувствительного к регистру модификатора ¹ или добавлением ASCII-безопасного модификатора ²в различных местах, часто требуя, чтобы автор регулярных выражений определенно знал о лигатуре переменной ширины.
Первый вариант (который является единственнымehensive one) сопоставляет переменную ширину с двумя взглядами: сначала для шестизначной версии (без лигатур, как указано в первой цитате ниже), а затем для любых лигатур, используя forward lookahead (с нулевой шириной!) для st
(включая лигатуры), а затем для учета ширины одного символа с .
Два сегмента perlre
справочной страницы :
¹ Модификатор без учета регистра /i
& лигатуры
Существует несколько символов Unicode, которые соответствуют последовательности из нескольких символов в /i
.Например, «LATIN SMALL LIGATURE FI» должно соответствовать последовательности fi
.Perl в настоящее время не может сделать это, когда несколько символов находятся в шаблоне и разделены между группами, или когда один или несколько количественно определены.Таким образом
"\N{LATIN SMALL LIGATURE FI}" =~ /fi/i; # Matches [in perl 5.14+]
"\N{LATIN SMALL LIGATURE FI}" =~ /[fi][fi]/i; # Doesn't match!
"\N{LATIN SMALL LIGATURE FI}" =~ /fi*/i; # Doesn't match!
"\N{LATIN SMALL LIGATURE FI}" =~ /(f)(i)/i; # Doesn't match!
² ASCII-безопасный модификатор /aa
(perl 5.14 +)
Запретить совпадения ASCII / не ASCII (например, k
с \N{KELVIN SIGN}
), укажите a
дважды, например /aai
или /aia
.(Первое вхождение a
ограничивает \d
и т. Д., А второе вхождение добавляет ограничения /i
.) Но обратите внимание, что кодовые точки вне диапазона ASCII будут использовать правила Unicode для сопоставления /i
, поэтомумодификатор на самом деле не ограничивает вещи только ASCII;он просто запрещает смешивание ASCII и не-ASCII.
ToПодводя итог, этот модификатор обеспечивает защиту для приложений, которые
не хочу подвергаться воздействию всего Unicode. Указав это дважды, вы получите
дополнительная защита.