1

I'm trying to highlight (with <mark) a search string inside another string, but it shouldn't be part of a tag (i.e. te in <cite> shouldn't match, but te in test should). I've been using code like this to replace the match with the second regex listed, but that only works nestted.

someElement.innerHTML.replace(regex, function(full, before, match, after) {
  return before + '<mark>' + match + '</mark>' + after;
});

Suggestions I have tried:

  • <\/\w*>(\w*\s*)*(te)(\w*\s*)*<([a-z]*\s*\w*="\w*")*> (doesn't match at all?)
  • (<.+?>[^<>]*?.*)(te)(.*[^<>]*?<.+?>) (only works on the nested tags)
  • ((<.+?>[^<>]*?)?.*)(te)(.*([^<>]*?<.+?>)?) (.replace gives undefined's)

Example:

String to wrap: te

Input text:

‘This is a test string’
<cite> — some test wrapped too</cite>

Expected output:

‘This is a <mark>te</mark>st string’
<cite> — some <mark>te</mark>st wrapped too</cite>

I've browsed a lot of "duplicates", but couldn't find an exact one, but if someone can lead me to a working example, that'd be lovely too, thanks!

An answer that's now deleted which worked the best for me is (te)(?![^<]*>) (by revo). This does however not work if the next char is >, but I'll see that as a unsolved edge case.

double-beep
  • 5,031
  • 17
  • 33
  • 41
Haroen Viaene
  • 1,329
  • 18
  • 33

1 Answers1

3

Regex:

(te)(?!\w*>)

It benefits from a negative lookahead to check if it is within an opening / closing tag or not. (?!\w*>) this will ignore any te that is followed by any word characters and > (which possibly denotes being within a tag name.)

Failing case:

When there is potentially a string like test> (unpaired) within input string even though it is not a tag it doesn't match.

Live demo

Community
  • 1
  • 1
revo
  • 47,783
  • 14
  • 74
  • 117
  • What exactly is the point of the ` ` in the negative lookahead? – Haroen Viaene Aug 28 '16 at 19:44
  • An space will avoid words like `test >` to be ignored since you may have a `>` within a literal text too. I modified regex to cover more possible cases. – revo Aug 28 '16 at 20:54