Разрыв слова регулярного выражения с помощью диакритических знаков юникода
-
19-09-2019 - |
Вопрос
Я работаю над приложением, которое выполняет поиск текста с использованием регулярных выражений на основе входных данных пользователя.Один из вариантов, который есть у пользователя, - включить подстановочный знак "Соответствует 0 или более символам", используя звездочку.Мне нужно, чтобы это совпадало только между границами слов.Моей первой попыткой было преобразовать все звездочки в (?:(?=\B).)*
, что прекрасно работает в большинстве случаев.Где это не удается, так это, по-видимому .Net считает позицию между символом юникода с диакритическим знаком и другим символом разрывом слов.Я считаю это ошибкой и отправил ее в Сайт обратной связи Майкрософт.
Тем временем, однако, мне нужно внедрить функциональность и отправить продукт.Я подумываю об использовании [\p{L}\p{M}\p{N}\p{Pc}]*
в качестве текста замены, но, честно говоря, нахожусь в положении "Я действительно не понимаю, что это будет делать".Я имею в виду, я могу прочитать спецификации, но не уверен, что смогу достаточно протестировать это, чтобы убедиться, что оно делает то, что я ожидаю.Я просто не знал бы всех граничных условий для проверки.Приложение используется представителями разных культур, многие из которых проживают в племенных районах, поэтому необходимо поддерживать любые системы письма, включая те, которые используют разрывы слов нулевой ширины.
Есть ли у кого-нибудь более элегантное решение, или он мог бы подтвердить / исправить приведенный выше код, или предложить несколько советов?
Спасибо за вашу помощь.
Решение
Эквивалент /(?:(?=\B).)*/
в контексте unicode было бы:
/
(?:
(?: (?<=[\p{L}\p{M}\p{N}\p{Pc}]) (?=[\p{L}\p{M}\p{N}\p{Pc}])
| (?<![\p{L}\p{M}\p{N}\p{Pc}]) (?![\p{L}\p{M}\p{N}\p{Pc}])
)
.
)*
/
... или несколько упрощенный:
/(?:[\p{L}\p{M}\p{N}\p{Pc}]+|[^\p{L}\p{M}\p{N}\p{Pc}]+)?/
Это соответствовало бы либо последовательности слов, либо последовательности, не состоящей из слов (интервалы, знаки препинания и т.д.), возможно, пустой.
Нормальная или отрицаемая граница слова (\b
или \B
) - это, по сути, двойной осмотр.Один оглядывается назад, чтобы убедиться в типе персонажа, который предшествует текущей позиции.Точно так же тот, кто смотрит вперед.
Во втором регулярном выражении я удалил обходные пути и вместо этого использовал простые классы символов.