Skip to content

1. (?s)<td\b[^>]*>(.*?)</td>

This is the one that grabs the inner content of <td> cells.

  • (?s)

    • This is a flag: it turns on “dotall” mode.

    • Normally . does not match newlines. With (?s), . matches everything including \n.

    • That way, if your <td> has line breaks, it still gets captured.

  • <td

    • Match the literal string <td.
  • \b

    • Word boundary. Ensures we match <td as a whole word.

    • Without this, <tdx> or <tdwhatever> could match by accident.

  • [^>]*

    • [] = character class.

    • ^> = “not >”.

    • * = zero or more times.

    • So: “match everything that is not a > until we hit the closing > of the <td> tag”.

    • This swallows attributes like align="center" or class="oldinfo".

  • >

    • Literal closing angle bracket of the opening tag.
  • (.*?)

    • A capturing group (the (...) part).

    • . = any character.

    • * = zero or more times.

    • ? = lazy mode → take as little as possible while still making the whole regex succeed.

    • So this group captures “everything inside the <td> ... </td> cell”.

  • </td>

    • Match the literal closing tag.

✅ End result: capture the inside text/HTML of any <td> cell.


2. (?s)<[^>]+>

This is the one we used to strip tags inside <td>.

  • (?s)

    • Again, dotall mode (to allow . to match newlines inside tags).
  • <

    • Match literal <.
  • [^>]+

    • [] = character class.

    • ^> = “not >”.

    • + = one or more times.

    • So: “one or more characters until the next >”.

  • >

    • Match the literal >.

✅ End result: this matches any HTML tag like <br/>, <b>, <td align="...">.
When we ReplaceAllString(..., ""), we effectively delete all tags and leave only the raw text.


Put together

  1. First regex finds the cell contents (active on <br/>2025-02-18 15:14:29).

  2. Second regex cleans out any leftover tags so you’re left with active on 2025-02-18 15:14:29.


👉 Quick mnemonic:

  • [^>] → “not a >” → used for matching attributes or inside tags.

  • .*? → “anything, lazily” → used for capturing content until the next closing tag.

  • (?s) → “dotall” → make sure . really means any character.


Do you want me to write a few practice regex drills for you (with examples + answers), so you can reinforce this?

Regex Doc

Regex quick reference

Basics

. – any character
^ – start of string
$ – end of string
– escape special char

Character classes

\d – digit
\D – non-digit
\w – word char
\W – non-word char
\s – whitespace
\S – non-whitespace

[ ] – character set
[^ ] – negated set
( ) – group
(?: ) – non-capturing group
| – OR

Boundaries

\b – word boundary
\B – no boundary

Quantifiers

a* – zero or more
a+ – one or more
a? – zero or one
a{3} – exactly 3
a{3,} – 3 or more
a{3,5} – 3 to 5

Greedy / lazy

.* – greedy match
.*? – lazy match

Lookarounds

(?= ) – positive lookahead
(?! ) – negative lookahead
(?<= ) – positive lookbehind
(?<! ) – negative lookbehind

Anchors

\A – start of text
\Z – end of text
\G – end of last match

Flags (inline)

(?i) – ignore case
(?m) – multiline mode
(?s) – dot matches newline


Ranges between markers

X.?Y – text from X until next Y
.
? – html tag including content
(.*?) – capture content only
(?s) – dot matches newline