Многократные осмотры и игнорирование внутри тегов - PullRequest
0 голосов
/ 24 сентября 2019

Я хочу найти текст, который не является частью другого слова (пусть это работает), но я также хочу не найти текст, если он находится внутри тега <a>

"Java <li>Javascript</li> <a href="">Some Java here</a> more java"

var regex2 = new RegExp(`(?<![a-z])Java(?![a-z])`, "gi");

text = text.replace(regex2, '++JavaUpdated++');

Выше работает, но ниже с дополнительными взглядами не

var regex2 = new RegExp(`(?<![a-z])(?<!<a.*)Java(?!.*<\/a>)(?![a-z])`, "gi");

Ответы [ 3 ]

2 голосов
/ 25 сентября 2019

Не разбирайте HTML с регулярным выражением , но если вы настаиваете ...

Вы можете использовать следующее выражение регулярного выражения, если вы используете браузер, который позволяет просматривать вид сзади (см. Ниже)):

(?<![^\s])Java(?![^\s])(?!(.(?!<a))*<\/a>)

Regex Demo

По сути, мы проверяем, что нет ничего впереди или после Java, кроме пробелов, а затем используем отрицательный прогноздля проверки текста в тегах.

Я заметил, что вы используете отрицательный lookbehind в своем исходном регулярном выражении - это на самом деле не поддерживается JavaScript до 2018 года, поэтому вы можете захотетьзнать об этом.Взгляды доступны только в браузерах , поддерживающих стандарт ECMA2018 .

Если вы хотите решить эту проблему без негативного взгляда, вы можете попробовать:

(?:\s$|^)Java(?![^\s])(?!(.(?!<a))*<\/a>)

Regex Demo

По сути, говоря, что не соответствует Java, если ему предшествует что-либо, кроме пробела или начала строки (иначе, будет частью слова).

0 голосов
/ 25 сентября 2019

Предполагая, что вам не нужно обрабатывать, где текст может разбиваться на отдельные текстовые узлы, приведенный ниже фрагмент должен охватывать логику.Идея состоит в том, чтобы просто пройти узлы Text в DOM и игнорировать любые теги привязки по пути.

// Your RegExp, just as a literal
const re = /(?<![a-z])Java(?![a-z])/gi

const walkTextNodesIgnoringAnchors = (el, fn) =>
  el.childNodes.forEach(child => {
    // Ignore anchors
    if (child.nodeName === 'A') return
    
    // On Text nodes, call fn
    else if (child.nodeName === '#text') fn(child)
    
    // Otherwise, recursively walk further down
    else walkTextNodes(child, fn)
  })

const textEl = document.querySelector('.js-text')

walkTextNodesIgnoringAnchors(textEl, (textNode) => {
  textNode.textContent = textNode.textContent.replace(re, '++JavaUpdated++')
})
<div class="js-text">Java Javascript <a href="">Some Java here</a> more java</div>
0 голосов
/ 25 сентября 2019

Один из подходов к этому - разделить строку на теги <a>, затем независимо обработать каждую часть строки, заменив Java на ++JavaUpdated++ только тогда, когда часть не начинается с <a:

const str = 'Java <li>Javascript</li> <a href="">Some Java here</a> more java';

let newstr = str.split(/(<a.*?<\/a>)/)
                .map(v => (v.slice(0, 2) == '<a') ? v : v.replace(/\bJava\b/i, '++JavaUpdated++'))
                .join();

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