Последствия вставки положительного взгляда в произвольное регулярное выражение для имитации смещения байта

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

10

Решение

В режиме без UTF, библиотека UTF-8

Предполагая, что ваша библиотека 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-режиме, библиотека UTF-8

Режим UTF может быть активирован u флаг в шаблоне передан preg_* функция, или указав (*UTF), (*UTF8), (*UTF16), (*UTF32) глаголы в начале шаблона.

В режиме UTF, класс персонажа [] и точка метасимвол . будет соответствовать одной кодовой точке в допустимом диапазоне символов Юникода и не является суррогатом. Поскольку одна кодовая точка может быть закодирована в 1–4 байта в UTF-8, и из-за схемы кодирования UTF-8 невозможно использовать конструкцию класса символов для сопоставления одного байта для значений в диапазоне от 0x80 до 0xFF ,

В то время как \C специально разработан для соответствия одному элементу данных (который составляет один байт в UTF-8) независимо от того, включен режим UTF или нет, он не поддерживается в структуре просмотра в режиме UTF.

Библиотека UTF-16 и UTF-32

Я не знаю, кто-нибудь на самом деле компилирует 16-битную или 32-битную библиотеку PCRE, включает ее в библиотеку PHP и фактически заставляет ее работать. Если кто-нибудь знает о такой сборке существа широко используется в дикой природе, пожалуйста, пинг мне. На самом деле я понятия не имею, как строка и смещение от PHP передаются в C API PCRE, в зависимости от того, какой результат preg_* функции могут отличаться.

На уровне C API библиотеки PCRE вы можете работать только с единицей данных, которая находится в 8-битных единицах для 8-битной библиотеки, в 16-битных единицах для 16-битной библиотеки и в 32-битных единицах для 32-битной библиотеки. ,

Для 8-битной библиотеки (UTF-8) 1 единица данных является 8-битной или 1 байтом, поэтому нет особых препятствий для задания смещения в байтах, будь то в качестве параметра для функции или в качестве конструкции регулярного выражения.

Regex конструкции

В не-UTF режиме, класс персонажа []точка . а также \C соответствует ровно 1 единице данных.

  • \C соответствует 1 блоку данных, независимо от режима UTF или не UTF. Однако его нельзя использовать для просмотра в UTF-режиме.

    СООТВЕТСТВИЕ ЕДИНОМУ БЛОКУ ДАННЫХ

    Вне класса символов, escape-последовательность \C соответствует любым данным
    единицы, независимо от того, установлен ли режим UTF.

  • . соответствует 1 блоку данных в режиме без UTF.

    Общие комментарии о режимах UTF

    […]
    1. Метасимвол точки соответствует одному символу 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.

6

Другие решения

Вы могли бы попробовать /(?<=[\x00-\xFF]{n})some expression/ для’-byte смещение. Добавьте якоря или другие мягкие якоря, которые выполняют начальное выравнивание.

1

По вопросам рекламы [email protected]