0

I'm trying to match [abc] unless it's "escaped" by [] from both sides (so [[abc]] is considered as escaped, but not [[abc] or [abc]]).

Closest thing I could find is (?<!\[)\[abc\](?!\]) from Match "ABC" from *ABC*, but not from **ABC**, but it ignores match if it's escaped from only one side.

blhsing
  • 77,832
  • 6
  • 59
  • 90
maxc137
  • 1,371
  • 14
  • 26
  • 2
    @WiktorStribiżew I noticed that you removed the `c#` tag from this question. The description of the `regex` tag says "all questions with this tag should also include a tag specifying the applicable programming language or tool", so the `c#` tag that you removed was not insignificant and I therefore added it back along with `.net`, the regex engine that C# uses. My answer for example uses the support for variable-length lookbehind afforded by .NET. – blhsing Aug 26 '21 at 01:38
  • **This is a duplicate of [Match pattern not preceded or followed by string](https://stackoverflow.com/questions/59907883/match-pattern-not-preceded-or-followed-by-string)** – Wiktor Stribiżew Aug 26 '21 at 07:52
  • @WiktorStribiżew that question is a bit more complex + this one has a `.net` specific solution which might not be suitable for that one – maxc137 Aug 26 '21 at 11:17
  • No regex here is .NET specific and will work in Java, Python, even JavaScript now. – Wiktor Stribiżew Aug 26 '21 at 11:19

2 Answers2

7

The lookahead could be either at the left, or at the right to allow a single backet on the left or right, but not a double square bracket on the other side.

(?<!\[)\[abc]|\[abc](?!])

Regex demo

The fourth bird
  • 127,136
  • 16
  • 45
  • 63
  • Hi, great quick solution (+1), but I thought you'd be interested in reading about a different approach of mine that helps avoid pattern duplication. Feedbacks from an experienced regex user like you would be greatly appreciated. – blhsing Aug 26 '21 at 01:22
3

@Thefourthbird's answer works, but would require that the main pattern abc be repeated, which goes against the DRY principle that most are encouraged to follow.

In the interest of maximizing code reuse, one approach would be to use a capture group to capture [abc] and then use it in a negative lookbehind pattern to ensure that it is not both preceded by a [ and followed by a ]:

(\[abc])(?<!\[\1(?=]))

Demo

Note that this works for C# because .NET happens to support variable-length lookbehind patterns, which aren't supported by many other regex engines.

blhsing
  • 77,832
  • 6
  • 59
  • 90