C# Regex Find Phrase in HTML exclude specific tags

Viewed 56

I have HTML text and I have a specific phrase. I need to find my phrase inside HTML text and highlight it, but I have to skip my phrase if it's inside h or a tags

For Example: Here is my phrase: "phrase to highlight"

This is my HTML Text

<p>Here starts text and here is phrase to highlight</p>
<a>here, phrase to highlight, supposed to be skipped</a>
<h3>here, phrase to highlight, supposed to be skipped</h3>
<div class="phrase to highlight">Here phrase to highlight must be highlighted again</div>

p and div tags should highlight my phrase, a and any h tags should skip my phrase.

I do negative lookbehinds to find my phrase and make sure it's not an HTML attribute

var Pattern = $"(?i)(?<!</?[^>]*|&[^;]*)(\bphrase to highlight\b)";

How can I modify my regex to exclude a and h tags?

1 Answers

If there are no nested a and h tags, use

(?<!</?[^>]*|&[^;]*|<(?:a|h\d)(?:\s[^>]*)?>[^<]*)(\bphrase to highlight\b)

See proof.

Explanation

--------------------------------------------------------------------------------
  (?<!                     look behind to see if there is not:
--------------------------------------------------------------------------------
    <                        '<'
--------------------------------------------------------------------------------
    /?                       '/' (optional (matching the most amount
                             possible))
--------------------------------------------------------------------------------
    [^>]*                    any character except: '>' (0 or more
                             times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
   |                        OR
--------------------------------------------------------------------------------
    &                        '&'
--------------------------------------------------------------------------------
    [^;]*                    any character except: ';' (0 or more
                             times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
   |                        OR
--------------------------------------------------------------------------------
    <                        '<'
--------------------------------------------------------------------------------
    (?:                      group, but do not capture:
--------------------------------------------------------------------------------
      a                        'a'
--------------------------------------------------------------------------------
     |                        OR
--------------------------------------------------------------------------------
      h                        'h'
--------------------------------------------------------------------------------
      \d                       digits (0-9)
--------------------------------------------------------------------------------
    )                        end of grouping
--------------------------------------------------------------------------------
    (?:                      group, but do not capture (optional
                             (matching the most amount possible)):
--------------------------------------------------------------------------------
      \s                       whitespace (\n, \r, \t, \f, and " ")
--------------------------------------------------------------------------------
      [^>]*                    any character except: '>' (0 or more
                               times (matching the most amount
                               possible))
--------------------------------------------------------------------------------
    )?                       end of grouping
--------------------------------------------------------------------------------
    >                        '>'
--------------------------------------------------------------------------------
    [^<]*                    any character except: '<' (0 or more
                             times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
  )                        end of look-behind
--------------------------------------------------------------------------------
  (                        group and capture to \1:
--------------------------------------------------------------------------------
    \b                       the boundary between a word char (\w)
                             and something that is not a word char
--------------------------------------------------------------------------------
    phrase to                'phrase to highlight'
    highlight
--------------------------------------------------------------------------------
    \b                       the boundary between a word char (\w)
                             and something that is not a word char
--------------------------------------------------------------------------------
  )                        end of \1
Related