Каковы будут последствия добавления положительного взгляда за n-байтами, (?<=\C{n})
в начало любого произвольного регулярного выражения, особенно когда используется для операций замены?
По крайней мере, в PHP функции соответствия регулярному выражению, preg_match
а также preg_match_all
, разрешить сопоставление начинать после заданного байтового смещения. Никакой соответствующей функции нет ни в одной из других функций PCRE PHP — вы можете указать ограничение на количество замен, выполненных preg_replace
например, но не то, что совпадения этих замен должны произойти после n-байтов.
Очевидно, будут некоторые (давайте назовем их тривиальными) последствия для производительности и читабельности, но будут любые (нетривиальные) воздействия, такие как совпадения, становящиеся несоответствиями (кроме случаев, когда они не смещены на n байтов) или замены, становящиеся искаженными ?
Некоторые примеры:
/some expression/
становится /(?<=\C{4})some expression/
для смещения 4 байта
/(this) has (groups)/i
становится /(?<=\C{2})(this) has (groups)/i
для 2-байтового смещения
Насколько я могу судить, и из ограниченных тестов, которые я запускал, добавление в этом lookbehind эффективно имитирует этот параметр смещения и не связывается с другими взглядами, заменами или другими шаблонами управления; но я также не эксперт по Regex.
Я пытаюсь определить, есть ли какие-либо вероятные последствия для создания расширений функций замены / фильтрации, вставляя n-байтовый lookbehind в шаблоны. Он должен работать так же, как работает параметр смещения функций сопоставления, поэтому просто запустите выражение для substr( $subject, $offset )
не будет работать по тем же причинам, что не для preg_match
(в первую очередь это отрезает любые взгляды и ^
тогда некорректно совпадает с началом подстроки, а не с исходной строкой).
Предполагая, что ваша библиотека PCRE в комплекте с PHP скомпилирована как 8-битная библиотека (UTF-8), затем в режиме без UTF
\C
эквивалентно
[\x00-\xff]
а также
(?s:.)
Любой из них может быть использован в качестве замены для offset
поле в preg_match
а также preg_match_all
функции.
В режиме без UTF все они соответствуют 1 единице данных, что составляет 1 байт в 8-битной (UTF-8) библиотеке PCRE, и они соответствуют всем 256 возможным различным значениям.
Режим UTF может быть активирован u
флаг в шаблоне передан preg_*
функция, или указав (*UTF)
, (*UTF8)
, (*UTF16)
, (*UTF32)
глаголы в начале шаблона.
В режиме UTF, класс персонажа []
и точка метасимвол .
будет соответствовать одной кодовой точке в допустимом диапазоне символов Юникода и не является суррогатом. Поскольку одна кодовая точка может быть закодирована в 1–4 байта в UTF-8, и из-за схемы кодирования UTF-8 невозможно использовать конструкцию класса символов для сопоставления одного байта для значений в диапазоне от 0x80 до 0xFF ,
В то время как \C
специально разработан для соответствия одному элементу данных (который составляет один байт в UTF-8) независимо от того, включен режим UTF или нет, он не поддерживается в структуре просмотра в режиме UTF.
Я не знаю, кто-нибудь на самом деле компилирует 16-битную или 32-битную библиотеку PCRE, включает ее в библиотеку PHP и фактически заставляет ее работать. Если кто-нибудь знает о такой сборке существа широко используется в дикой природе, пожалуйста, пинг мне. На самом деле я понятия не имею, как строка и смещение от PHP передаются в C API PCRE, в зависимости от того, какой результат preg_*
функции могут отличаться.
На уровне C API библиотеки PCRE вы можете работать только с единицей данных, которая находится в 8-битных единицах для 8-битной библиотеки, в 16-битных единицах для 16-битной библиотеки и в 32-битных единицах для 32-битной библиотеки. ,
Для 8-битной библиотеки (UTF-8) 1 единица данных является 8-битной или 1 байтом, поэтому нет особых препятствий для задания смещения в байтах, будь то в качестве параметра для функции или в качестве конструкции регулярного выражения.
В не-UTF режиме, класс персонажа []
точка .
а также \C
соответствует ровно 1 единице данных.
\C
соответствует 1 блоку данных, независимо от режима UTF или не UTF. Однако его нельзя использовать для просмотра в UTF-режиме.
СООТВЕТСТВИЕ ЕДИНОМУ БЛОКУ ДАННЫХ
Вне класса символов, escape-последовательность
\C
соответствует любым данным
единицы, независимо от того, установлен ли режим UTF.
.
соответствует 1 блоку данных в режиме без UTF.
Общие комментарии о режимах UTF
[…]
- Метасимвол точки соответствует одному символу UTF вместо одного
блок данных.
Класс символов соответствует 1 единице данных в режиме без UTF. В документации явно не указано это, но это подразумевается формулировкой.
КВАДРАТНЫЕ КРОНШТЕЙНЫ И КЛАССЫ ХАРАКТЕРА
[…]Класс символов соответствует одному символу в теме. В UTF
В этом режиме символ может иметь длину более одного блока данных.
К тому же выводу можно прийти, взглянув на верхний предел \x{hh...}
синтаксис для указания символа шестнадцатеричным кодом в не-UTF-режиме. Посредством тестирования последнее предложение о суррогате, похоже, не относится к не-UTF-режиму.
Символы, которые указаны с использованием восьмеричных или шестнадцатеричных чисел,
ограничены определенными значениями, а именно:8-bit non-UTF mode less than 0x100 8-bit UTF-8 mode less than 0x10ffff and a valid codepoint 16-bit non-UTF mode less than 0x10000 16-bit UTF-16 mode less than 0x10ffff and a valid codepoint 32-bit non-UTF mode less than 0x100000000 32-bit UTF-32 mode less than 0x10ffff and a valid codepoint
Недопустимые кодовые точки Unicode находятся в диапазоне от 0xd800 до 0xdfff (так
называемые «суррогатные» кодовые точки), и 0xffef.
Все смещения, предоставленные и возвращенные в количестве единиц данных:
Строка для сопоставления
pcre_exec()
Строка темы передается
pcre_exec()
в качестве указателя вsubject
,
длина вlength
и начальное смещение вstartoffset
, Единицы для
length
а такжеstartoffset
байты для 8-битной библиотеки, 16-битных данных
элементы для 16-битной библиотеки и 32-битные элементы данных для 32-битной
библиотека.
Как
[…]pcre_exec()
возвращает захваченные подстрокиКогда совпадение успешно, информация о захваченных подстроках
возвращается парами целых чисел, начиная с начала вектора,
и продолжая до двух третей его длины самое большее. Первый
элемент каждой пары устанавливается на смещение первого символа в
подстрока, а вторая устанавливается на смещение первого символа
после окончания подстроки. Эти значения всегда единица данных вне
устанавливает, даже в режиме UTF.
Вы могли бы попробовать /(?<=[\x00-\xFF]{n})some expression/
для’-byte
смещение. Добавьте якоря или другие мягкие якоря, которые выполняют начальное выравнивание.