Вот решение, которое использует балансировочные группы, особенность. NET Regex, которая позволяет использовать стек, чтобы убедиться, что разделители, в данном случае [\s*"
и "\s*]
, сбалансированы. Это делает все ваши совпадения правильными и должно быть довольно хорошо масштабируемым.
\[\s*"(?>(?!\[\s*"|"\s*]).|\[\s*"(?<Depth>)|"\s*](?<-Depth>))*(?(Depth)(?!))"\s*]
Разбивка этого регулярного выражения выглядит следующим образом:
\[\s*" match the first delimiter
(?> start atomic group (no backtracking allowed)
(?!\[\s*"|"\s*]). look ahead, make sure next character isn't a delimiter, then capture that character
|\[\s*"(?<Depth>) alternatively, capture an opening delimiter and push it to the <Depth> stack
|"\s*](?<-Depth>) alternatively, capture a closing delimiter and pop the top of the <Depth> stack
)* close atomic group, repeat it 0 or more times
(?(Depth)(?!)) if the Depth stack has anything in it, fail the match
"\s*] capture the final closing delimiter
разделители просты: \[
- открывающая скобка, затем \s*
любое количество пробелов, затем "
кавычка. Открывающая скобка должна быть исключена, потому что она имеет особое значение в Regex, но закрывающая скобка, используемая в закрывающем разделителе, необязательно должна быть связана с тем, что ее специальное значение связано с открывающей скобкой, поэтому закрывающий разделитель проще: "\s*]
, только обратная открывающей.
Используя это, вы получите следующие совпадения:
"My issue" / ["Error] ["some!+ name"]"] * 3 + 4 -> ["Error] ["some!+ name"]"]
3*12 * ["Country"] + ["City".] * 2 + [""] -> ["Country"] , [""]
["Spain12"] * ["Name "Industry""] -> ["Spain12"] , ["Name "Industry""]
[ "Italy" ] * 5 - [ "France","Paris" ] + 2 -> [ "Italy" ] , [ "France","Paris" ]
[Madrid] -> NO MATCHES
РЕДАКТИРОВАТЬ: Для получения дополнительной информации о балансировочных группах, см. этот замечательный ответ:
Что такое балансировочные группы регулярного выражения?