zimdanen
zimdanen

Reputation: 5626

Match end and beginning characters or neither

I'm trying to make a regex that would match a character at the beginning and end of the expression or match without the character in either place. I know I can do this using a | and two complete expressions, but is it possible to do so in one expression?

Example text:

This is some groovy_[Item]text[/Item]_right here.  And here's some_[Item]more[/Item].

Current regex:

_?\[Item\]([^\[]+)\[\/Item\]_?

For the above, the regex would match _[Item]text[/Item]_ and _[Item]more[/Item]. However, for the second match, I don't want the leading _, since the trailing _ isn't there.

I could obviously use this regex and it would work:

_\[Item\]([^\[]+)\[/Item\]_|\[Item\]([^\[]+)\[/Item\]

I just want to know if there's a way to do it without the doubling up of the meat of the expression.

Upvotes: 1

Views: 46

Answers (2)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626794

You can use a conditional regex in .NET:

( )?\[Item\]([^\[]+)\[/Item\](?(1) )

See regex demo

enter image description here

Here, we match an optional space with ( )? and then, at the end, if we matched it, we want to also match a space with (?(1) ).

If you want to match any Unicode spaces, use \p{Zs} instead of just a space.

Upvotes: 2

Federico Piazza
Federico Piazza

Reputation: 30995

You can use ? operator after the space to make it optional, capture it and reference it:

(_?)\[Item](.*?)\[/Item]\1
  ^------------ Here ----^

Working demo

enter image description here

Upvotes: 2

Related Questions