Ответ 1
(?!<a[^>]*?>)(Test)(?![^<]*?</a>)
то же, что и zb226, но оптимизировано с ленивым соответствием
Кроме того, использование регулярных выражений на необработанном HTML не рекомендуется.
У меня есть следующая строка:
Lorem ipsum Test dolor sit amet, consetetur sadipscing elitr, sed diam nonumy <a href="#" onclick="location.href='http://Test.com/url'; return false;">Test</a> eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd sed Test dolores et ea rebum. Stet clita kasd gubergren, no sea <a href="#" onclick="location.href='http://url.com'; return false;">Test xyz</a> takimata sanctus est Lorem ipsum dolor sit amet.
Теперь я бы заменил строку "Test" вне тегов, а не между тегами (например, заменил на "1234").
Lorem ipsum 1234 dolor sit amet, consetetur sadipscing elitr, sed diam nonumy <a href="#" onclick="location.href='http://Test.com/url'; return false;">Test</a> eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd sed 1234 dolores et ea rebum. Stet clita kasd gubergren, no sea <a href="#" onclick="location.href='http://url.com'; return false;">Test xyz</a> takimata sanctus est Lorem ipsum dolor sit amet.
Я начал с этого регулярного выражения: (?!<a[^>]*>)(Test)([^<])(?!</a>)
Но две проблемы не решены:
<a href="#" onclick="location.href='http://Test.com/url'; return false;">
)<a href="#" onclick="location.href='http://url'; return false;">Test xyz</a>
)Я надеюсь, что у кого-то есть решение этой проблемы.
(?!<a[^>]*?>)(Test)(?![^<]*?</a>)
то же, что и zb226, но оптимизировано с ленивым соответствием
Кроме того, использование регулярных выражений на необработанном HTML не рекомендуется.
Ответ
использование
(Test)(?!(.(?!<a))*</a>)
объяснение
Позвольте мне напомнить вам о значении некоторых символов:
1) ?!
является негативным взглядом, например, r(?!d)
выбирает все r
, за которыми непосредственно не следует d
:
2) Поэтому никогда не начинайте отрицательный взгляд без персонажа. Просто (?!d)
бессмысленно
3) Чем ?
можно использовать как ленивый матч Например .+E
будет выбирать из
123EEE
вся строка 123EEE
. Тем не менее,. .+?E
выбирает столько "любой характер" (.+
), .+?E
необходимо. Было бы только выбрать 123E
.
Ответ:
Ответ простейшего заключается в том, что вы должны использовать (?!<a[^>]*?>)(Test)(?![^<]*?</a>)
<A [^> (?!<a[^>]*?>)(Test)(?![^<]*?</a>)
. Позвольте мне сначала объяснить, как сделать это короче.
Как упомянуто в 2), бессмысленно смотреть в будущее перед матчем. Таким образом, следующее эквивалентно ответу простейшего:
(Test)(?![^<]*?</a>)
Кроме того, <
не допускается, ленивый матч ?
является излишним, так что его также эквивалентно
(Test)(?![^<]*</a>)
При этом выбираются все Test
, за которыми не следует </a>
без символа <
между ними. Вот почему тест, который появляется до или после любого <a...>.. </a>
будет заменен.
Тем не менее, обратите внимание, что
Lorem Test dolor <a href="http://Test.com/url">Test <strong>dolor</strong></a> eirmod
будет изменен на
Lorem 1234 dolor <a href="http://1234.com/url">1234 <strong>dolor</strong></a> eirmod
Чтобы поймать это, вы можете изменить свое регулярное выражение на
(Test)(?!(.(?!<a))*</a>)
который делает следующее:
Выберите каждое слово
Test
, за которым не следует строка***</a>
где за каждым символом в***
не следует<a
.
Обратите внимание, что точка .
важно (см. 2)).
Обратите внимание, что ленивое совпадение типа (Test)(?!(.(?!<a))*?</a>)
не имеет значения, потому что вложенные ссылки недопустимы в HTML4 и HTML5 (что-то вроде <a href="#">..<a href="#">...</a>..</a>)
.
протист сказал
Кроме того, использование регулярных выражений в необработанном HTML не рекомендуется.
Я согласен с этим. Проблема в том, что это может вызвать проблемы, если тег не закрыт или не открыт. Например, все упомянутые решения будут изменены
Lorem Test dolor Test <strong>dolor</strong></a> eirmod
в
Lorem Test dolor Test <strong>dolor</strong></a> eirmod 1234 dolores sea 1234 takimata
Это должно сделать трюк:
(<a[^>]*>)(Test)(?![^<]*</a>)
Попробуйте сами на regexr.
Воскрешая этот древний вопрос, потому что у него было простое решение, о котором не упоминалось.
При всех отказах в использовании regex для синтаксического анализа html, это простой способ сделать это.
Метод Perl/PCRE
<a[^>]*>[^<]*<\/a(*SKIP)(*F)|Test
Общее решение
<a[^>]*>[^<]*<\/a|(Test)
В этой версии текст, подлежащий замене, записывается в группу 1, а замена выполняется простым обратным вызовом или лямбда.
Ссылка
Адаптируем предлагаемое решение @protist, в этом случае ищем фразу и исключаем любые совпадения внутри тега скрипта:
(?!<script[^>]*?>)(\bTest Phrase\b)(?![^<]*?<\/script>)
Ответ, предоставленный Адамом, хотя и является более кратким, требует больше времени для выполнения. Это можно доказать, отредактировав демоверсию, уже упомянутую в этом комментарии.