Regex для соответствия фразе, которая не находится внутри тега <a> - PullRequest
0 голосов
/ 12 мая 2018

У меня есть HTML-код, и мне нужно сопоставить фразу «Моя фраза», которой нет в теге <a>.

Фразы, которые НЕ должны совпадать:

1. <a>My Phrase</a>
2. <a><strong>My Phrase</strong></a>

Фразы, которые ДОЛЖНЫ совпадать:

3. <strong>My Phrase</strong>
4. My Phrase

Мое текущее решение использует отрицательный прогноз, чтобы найти совпадения, за которыми не следует закрывающий тег </a>:

My Phrase(?![^<]*>|[^<>]*<\/a)

https://regex101.com/r/n1d9KZ/1

Как видно из примера, он работает для обычных текстовых ссылок (случай 1), но не работает для случая 2, когда внутри тега «a» есть другие теги.

У кого-нибудь есть отрицательное регулярное выражение, работающее на обоих?

Я не могу использовать отрицательный lookbehind с регулярным выражением, таким как (?<!<a.*?>.*?)My Phrase(?!.*?<\/a>), потому что я получаю ошибку java.util.regex.PatternSyntaxException: Look-behind group does not have an obvious maximum length. Я также предпочел бы не анализировать HTML-код и удалять все текущие теги «a», поскольку мне нужно сохранить HTML-код без изменений и заменить «My Phrase» на «Another Phrase».

1 Ответ

0 голосов
/ 12 мая 2018

То, что вы пытаетесь сделать, не так тривиально, как на самом деле невозможно (только Джефф Дин) полностью обрабатывать HTML с помощью RegEx.

Поскольку везде могут быть новые строки со сложными атрибутами иВложение или просто недействительность.

В любом случае, в обстоятельствах вашего примера (без ссылок, без новых строк внутри и внутри тегов) вы можете сделать что-то вроде:

result = text.replace(/^.*?(My Phrase).*?$/gm, function($0,$1) { 
    var regEx = new RegExp("(" + $1 + ")");
    return $0.indexOf('<a') >= 0 ? $0 : $0.replace(regEx, '<b>$1</b>');
});

Я просто выделилсоответствует в примере, но вы могли бы сделать много вещей в обратном вызове: https://jsfiddle.net/8Ls0qbvj/

...