我想使用正则表达式从以下字符串中提取aaa
、bb b={{b}}bb bbb
和{ccc} ccc
:
zyx={aaa}, yzx={bb b={{b}}bb bbb}, xyz={{ccc} ccc}
注意:aaa
表示任意数量的字符的任意序列,因此没有确定的长度或模式。例如,{ccc} ccc
可以是{cccccccccc}cc {cc} cccc cccc
,或任何其他组合(,
我已经编写了以下正则表达式:
(?<a>[^{}]*)s*=s*{((?<v>[^{}]+)*)},*
此表达式提取aaa
,但由于嵌套的花括号,无法解析输入的其余部分,导致灾难性的回溯失败。
关于如何更新regex以正确处理嵌套括号,有什么想法吗?
(以防万一,如果你需要特定于引擎的选项,我会使用C#.NET Core 3.0。此外,我不想在代码上做任何魔术,而是只使用正则表达式模式。(
类似问题
匹配平衡括号的问题正则表达式与此问题类似,不同之处在于这里的括号不一定是平衡的,而是遵循x={y}
模式。
更新1
以下输入也是可能的:
yzx={bb b={{b}},bb bbb,},
注意{{b}}
和bbb
之后的,
。
更新2
我写了以下模式,这可以匹配第一个例子中的aaa
以外的任何内容:
(?<A>[^{}]*)s*=s*{(?<V>(?<S>([^{}]?){(?:[^}{]+|(?&S))+}))}(,|$)
Regex匹配,非常好
CCD_ 13可以工作。
string input = "zyx={aaa}, yzx={bb b={{b}}bb bbb}, yzx={bb b={{b}},bb bbb,}, xyz={{ccc} ccc}";
string pattern = "={(.*?)}(, |$)";
var matches = Regex.Matches(input, pattern)
.Select(m => m.Groups[1].Value)
.ToList();
foreach (var m in matches) Console.WriteLine(m);
输出
aaa
bb b={{b}}bb bbb
bb b={{b}},bb bbb,
{ccc} ccc
Regex。斯普利特,真的很好
我认为对于这份工作来说,Regex.Split
可能是一个更好的工具。
tring input = "zyx={aaa}, yzx={bb b={{b}}bb bbb}, yzx={bb b={{b}},bb bbb,}, ttt={nasty{t, }, }, xyz={{ccc} ccc}, zzz={{{{{{{huh?}";
var matches2 = Regex.Split(input, "(^|, )[a-zA-Z]+=", RegexOptions.ExplicitCapture); // Or "(?:^|, )[a-zA-Z]+=" without the flag
Console.WriteLine("-------------------------"); // Adding this to show the empty element (see note below)
foreach (var m in matches2) Console.WriteLine(m);
Console.WriteLine("-------------------------");
-------------------------
{aaa}
{bb b={{b}}bb bbb}
{bb b={{b}},bb bbb,}
{nasty{t, }, }
{{ccc} ccc}
{{{{{{{huh?}
-------------------------
注意:空元素存在是因为:
如果在输入字符串的开头或结尾找到匹配项,则在返回数组的开头或末尾会包含一个空字符串。
案例3
string input = "AAA={aaa}, BBB={bbb, bb{{b}}, bbb{b}}, CCC={ccc}, DDD={ddd}, EEE={00-99} ";
var matches2 = Regex.Split(input, "(?:^|, )[a-zA-Z]+="); // Or drop '?:' and use RegexOptions.ExplicitCapture
foreach (var m in matches2) Console.WriteLine(m);
{aaa}
{bbb, bb{{b}}, bbb{b}}
{ccc}
{ddd}
{00-99}