我正在寻找一种C#正则表达式解决方案来匹配/捕获一些小但复杂的数据块.我的数据库中有数千个非 struct 化数据块(来自第三方数据存储),它们看起来如下所示:

not BATTCOMPAR{275} and FORKCARRIA{ForkSpreader} and SIDESHIFT{WithSSPassAttachCenterLine} and TILTANGLE{4up_2down} and not AUTOMATSS{true} and not FORKLASGUI{true} and not FORKCAMSYS{true} and OKED{true}

我希望能够将其拆分成多个独立的部分(正则表达式匹配/捕获),如下所示:

not BATTCOMPAR{275} 
and FORKCARRIA{ForkSpreader} 
and SIDESHIFT{WithSSPassAttachCenterLine} 
and TILTANGLE{4up_2down} 
and not AUTOMATSS{true} 
and not FORKLASGUI{true} 
and not FORKCAMSYS{true} 
and OKED{true}

数据将始终符合以下规则:

  • 在每个数据块的末尾将有一个用大括号括起来的字符串,如下所示:{275}
  • "大括号分组"将始终出现在字符串的末尾,以notandand not或无开头."Nothing"与and相同,仅当它是字符串中的第一个块时才会出现.例如,如果我的and OKED{true}出现在字符串的开头,and将被省略,OKED{true}将不带任何前缀(空字符串).但它和AND是一样的.
  • 在运算符(andnotand not或Nothing)之后,将始终有一个字符串指示符,该指示符恰好在大括号分组之前结束.例如:BATTCOMPAR
  • appears%,字符串指示符将始终接触花括号分组,中间没有空格,但我不能appears%确定.正则表达式应该适应字符串指示符和左大括号之间可能有空格的情况.
  • 上述要点总结#1:每个块将有3个不同的子组:运算符(如and not)、字符串指示符(如BATTCOMPAR)和大括号分组(如{ForkSpreader}).
  • 以上要点总结#2:每个块将以3个列出的运算符中的一个开始,或者不以任何运算符开始,并以右大括号结束.可以保证整个段内只有一个左大括号和一个右大括号,并且它们将始终在段的结尾处组合在一起.不用担心在段的其他部分会遇到额外的/杂乱的花括号.

我已经try 了几种不同的正则表达式构造:

匹配大括号分组:

Regex regex = new Regex(@"{(.*?)}");
return regex.Matches(str);

上面的方法几乎可以用,但只得到了花括号分组,而没有得到相应的运算符和字符串指示符.

根据字符串前缀捕获数据块,try 匹配操作符字符串:

var capturedWords = new List<string>();
string regex = $@"(?<!\w){prefix}\w+";

foreach ( Match match in Regex.Matches(haystack, regex) ) {
    capturedWords.Add(match.Value);
}

return capturedWords;

上面的方法部分有效,但只获得了运算符,而不是我需要的全部块:(运算符+字符串指示符+大括号分组)

事先感谢您的帮助.

推荐答案

这对我很管用:/([and\s|or\s|not\s]+)?.*?(\{.*?\})/mgRegex Tester.

DotNet Fiddle岁时,这句话对我很管用:

()-捕获组

[and\\s|or\\s|not\\s]+?-以单个AND、OR、NOT或组合开头,后跟空格

.*?任意字符组合或无字符组合,例如BATTCOMPAR

\\{.*?\\}用大括号括起来的最后部分,它包含任意字符组合或不包含任何字符

string test = "not BATTCOMPAR{275} and FORKCARRIA{ForkSpreader} and SIDESHIFT{WithSSPassAttachCenterLine} and TILTANGLE{4up_2down} and not AUTOMATSS{true} and not FORKLASGUI{true} and not FORKCAMSYS{true} and OKED{true}";
Regex r = new Regex("([and\\s|or\\s|not\\s]+?.*?\\{.*?\\})", RegexOptions.Multiline);

//or if you need to account for matches where there is no
//prepending words ie. and, not and
//Regex r = new Regex("([and\\s|or\\s|not\\s|]+?.*?\\{.*?\\}|.*?\\{.*?\\})", RegexOptions.Multiline);

MatchCollection matches = r.Matches(test);
        
foreach(Match m in matches)
{
    Console.WriteLine(m.Value); 
}

Prints:

//not BATTCOMPAR{275}
//and FORKCARRIA{ForkSpreader}
//and SIDESHIFT{WithSSPassAttachCenterLine}
//and TILTANGLE{4up_2down}
//and not AUTOMATSS{true}
//and not FORKLASGUI{true}
//and not FORKCAMSYS{true}
//and OKED{true}

Csharp相关问答推荐

如何在C#中使用并行主义将数据表转换为动态对象

SortedSet.IsSubsetOf未按预期工作

当MD5被废弃时,如何在Blazor WASM中使用它?

总是丢弃返回的任务和使方法puc无效之间有区别吗?

获取ASP.NET核心身份认证cookie名称

. NET WireMock拒绝PostAsJsonAsync序列化

使用LayoutKind在C#中嵌套 struct .显式

将XPS转换为PDF C#

Polly v8—使用PredicateBuilder重试特定的状态代码

ASP.NET配置kestrel以使用Windows证书存储中的HTTPS

UWP应用程序try 将打包的本机.exe文件加载为C#程序集

使用泛型可空类实现接口

Blazor Web App WASM的两个独立项目令人困惑

正确处理嵌套的本机集合

HttpRequestMessage.SetPolicyExecutionContext不会将上下文传递给策略

有没有更好的方法来在CosmosDB上插入非id?

BFF到具有AAD/Entra ID B2C的内部API(.NET/ASP.NET核心/标识.Web)

升级后发出SWITCH语句

用于请求用户返回列表的C#Google API

如何消除Visual Studio错误,因为它不识别集合表达式的新C#12语法?