Исправление регулярных выражений для обхода ошибки 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+)?,

Другие вопросы по тегам