Lookbehind with "not character" ignores match at position 0

Viewed 36

I am trying to achieve a regex to select (%?[fFsmhd]){1,} preceded by + and not by \+.

My first option was (?<=[^\\]\+)(%?[fFsmhd]){1,} which seems to work except that the position 1 is never matched.

Test:

+fFsmhd (problem here, does not match)
+fFsmhd (matches)

A workaround I found to this problem is to replace the [^\\] for a nested negated lookbehind ending up with this disgusting thing: (?<=(?<!\\)\+)(%?[fFsmhd]){1,}

Test:

+fFsmhd (matches)
+fFsmhd (matches)

Is there any better way to achieve this without nest lookbehinds to do a simple [^\\]?

1 Answers

Without lookarounds it is not quite possible to do what you want. Actually, you have a flaw in the pattern: if there is a literal \ before +, it won't get matched. You need to account for any amount of double backslashes:

(?<=(?<!\\)(?:\\{2})*\+)(%?[fFsmhd])+

See this .NET regex demo.

The (?<=(?<!\\)(?:\\{2})*\+) lookbehind requires a + immediately on the left that is not immediately preceded with \ and then any amount of double backslashes.

Related