Как оптимизировать это регулярное выражение? - PullRequest
2 голосов
/ 13 августа 2010

Мой инструмент получает простой текст и постепенно генерирует "теги" на , заменяя термины из текста в тегах.Из-за существования некоторых составных терминов единственный способ (я думаю) - это использование ReplaceAll regex .

Благодаря друзьям stackoverflowВ своем последнем вопросе я получил отличное регулярное выражение для своего приложения, но после тестирования возникла новая необходимость:

"Регулярное выражение для замены всего слова вне тега ANDза пределами другого слова "

Оригинальный код:

String str = "world worldwide <a href=\"world\">my world</world>underworld world";
str = str.replaceAll("\\bworld\\b(?![^<>]*+>)", "repl");
System.out.println(str);

Теперь мне нужно заменить только" мир "(вне тегаконечно) и НЕ"подземный мир" или "во всем мире"

Ожидаемый результат :

repl worldwide <a href="world">my world</world>underworld repl

1 Ответ

3 голосов
/ 13 августа 2010

Я не думаю, что регулярное выражение - лучший инструмент для работы, но если вы просто хотите настроить и оптимизировать то, что у вас есть прямо сейчас, вы можете использовать слово border \b, отбросить ненужную группу захвата и опциональноспецификатор повторения и используйте притяжательное повторение:

\bworld\b(?![^<>]*+>)

\bworld\b гарантирует, что "world" будет окружен якорями границы слова нулевой ширины.Это предотвратит совпадение "world" в "underworld" и "worldwide".Обратите внимание, что определение границы слова может быть не совсем тем, что вы хотите, например, \bworld\b не будет соответствовать "world" в "a_world_domination".

Исходный шаблон также содержит подшаблон, который выглядит как (x+)?,Это, вероятно, лучше сформулировать как просто x*.То есть вместо «ноль или один» ? из «один или более» +, просто «ноль или более» *.

Группа захвата (…) функционально не требуется, и, похоже, вам не нужен захват для какой-либо замены в замене, поэтому избавление от нее может улучшить производительность (когда вам нужен аспект группировки, но не аспект захвата, вы можете использовать не-capturing group * вместо 1023 *).

Обратите внимание, что вместо [^<] мы теперь запрещаем обе скобки с [^<>].Теперь повторение может быть определено как притяжательное, так как в этом случае не требуется возврата.

([…] - это класс символов . Что-то вроде [aeiou]соответствует одному из строчных гласных. [^…] - это отрицательный класс символов. [^aeiou] соответствует одному из всего, кроме строчных гласных.)

Ofкурс (?!…) является отрицательным прогноз;он утверждает, что данный шаблон НЕ может быть сопоставлен.Таким образом, общая схема выглядит следующим образом:

\bworld\b(?![^<>]*+>)
\_______/\__________/ NOT the case that
 "world"                      the first bracket to its right is a closing one
 surrounded by
 word boundary anchors

Ссылки


Обратите внимание, что для получения обратной косой черты в строковом литерале Java вынужно удвоить его, поэтому весь шаблон как строковый литерал Java будет "\\bworld\\b(?![^<>]*+>)".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...