Исправление регулярных выражений для обхода ошибки ICU/RegexKitLite
Я использую RegexKitLite, который в свою очередь использует ICU в качестве своего движка. Несмотря на документацию, регулярное выражение типа /x*/ при поиске по "xxxxxxxxxxx" будет соответствовать пустой строке. Он ведет себя как /x*?/ Должен. Я хотел бы обойти эту ошибку, когда она присутствует, и я рассматриваю возможность перезаписать любой неэкранированный * как +, когда совпадение с регулярным выражением возвращает результат 0 длины. Мое наивное предположение состоит в том, что регулярное выражение с +s вместо * всегда будет возвращать подмножество правильных результатов. Каковы неожиданные последствия этого? Я иду правильным путем?
FWIW, ICU также предлагает оператор *+, но он также не работает.
РЕДАКТИРОВАТЬ: Я должен был быть более ясным: это для поля поиска интерактивного приложения. У меня нет контроля над регулярным выражением, которое вводит пользователь. Неправильная поддержка * кажется ошибкой в ICU. Я бы очень хотел, чтобы мне не нужно было включать это POS в мой код, но это единственная игра в городе.
4 ответа
Если вы просто измените каждый *
квантификатор к +
регулярное выражение не будет работать в тех случаях, когда *
должен был соответствовать ноль вхождений. Другими словами, проблема трансформируется из всегда совпадающего нуля в никогда не совпадающий с нулем. Если вы спросите меня, это бесполезно в любом случае.
Тем не менее, вы можете иметь возможность обрабатывать случай с нулевыми случаями отдельно, с отрицательным прогнозом. Например, x*
может быть переписан как (?:(?!x)|x+)
, Это отвратительно, я знаю, но это самое самостоятельное решение, которое я могу себе представить на данный момент. Вы должны были бы сделать это и для притяжательных звезд (*+
), но не отказываются звезды (*?
).
Вот это в виде таблицы:
ДО ПОСЛЕ x* (?:(?!x)|x+) x*+ (?:(?!x)|x++) Икс*? Икс*?Более сложные атомы должны иметь свои собственные круглые скобки:
(?: xyz) * (?: (?! (?: xyz)) | (?: xyz) +)Вы могли бы, вероятно, бросить их в поле зрения, но они не повредят ничему, кроме читабельности, и это в любом случае потеряно.:D Если
{min,}
а также {min,max}
формы также затронуты, они получили бы то же самое лечение (с теми же модификациями для притяжательных вариантов):x {0,} такой же как x * x {0, n } (?:(?! x) | x {1, n })
Мне приходит в голову, что (?(condition)yes-pattern|no-pattern)
- идеально подошло бы здесь; к сожалению, ICU не поддерживает их.
Я не могу сказать, где что-то пошло не так с рассматриваемым кодом, но я могу с уверенностью сказать, что этой конкретной ошибки нет в библиотеке ICU. (Я являюсь автором пакета регулярных выражений ICU.)
Я согласен с выражением, выраженным выше, что нужно попытаться не взломать проблему путем настройки шаблона регулярных выражений, а понять, что является основной проблемой. Вероятно, есть какая-то простая ошибка, которая не ясна из первоначального поставленного вопроса.
Да, используйте эту стратегию:
(псевдокод)
if ($ str = ~ / x * / && $ str = ~ / (x +) /) {print "'$ 1' \ n"; }
Но настоящая проблема - это ошибка, как вы говорите. С какой стати испорчена основная конструкция квантификаторов? Это не тот модуль, который вы должны включить в свой код.
И то и другое \*
а также [*]
буквальные звездочки, поэтому наивная замена может не сработать.
На самом деле, не делайте динамическое переписывание, это слишком сложно. Попробуйте сначала статически настроить свои регулярные выражения.
x*
эквивалентно x{0,}
а также (?:x+)?
,