When you need to match things "which are not between" other things, you may think to negative lookaround:
(?<!' *)\[[^\]]*\](?! *')
The matched group is $0
.
If I am not wrong, .NET regexps allow you to use non-fixed width expressions inside lookaround (but be aware that it is very expensive), so the regex above should do the job.
In other languages this is not allowed, but there is a workaround called "possessive quantifier" (*+
):
(?<!') *+(\[[^\]]*\]) *+(?!')
The matched group is $1
.
This works in all the languages in which negative lookaround and possessive quantifier are permitted (example).
About the meaning of *+
, I suggest you my answer on the topic.
But maybe the computationally simplest expression is:
[^'] *+(\[[^\]]*\]) *+[^']
The matched group is $1
.
Update
This is a kind of heuristics:
(?<=^[^'\n\r]*(('[^'\n\r]*){2})*)\[[^\]]*\]
Or, maybe faster:
\[[^\]]*\](?=[^'\n\r]*(('[^'\n\r]*){2})*$)
The matched group is $0
. Use it with multiline mode (m
flag).
It will work if apexes inside the fields are not allowed.