C# 正则表达式与平衡群

C# 正则表达式与平衡群,c#,.net,regex,balancing-groups,C#,.net,Regex,Balancing Groups,我被一个正则表达式卡住了: 我有一个带有数字和一个字母的输入字符串,可以在字符串内和括号之间包含更多的数字和字母: 仅举几个例子 26U(35O40) will be read as 26 and (35 or 40) 22X(34U(42O27)) will be read as 22 xor (34 and (42 or 27)) 21O(24U27) will be read as 21 or (24 and 27) 20X10X15 Will be read as 20 xor 10 x

我被一个正则表达式卡住了:

我有一个带有数字和一个字母的输入字符串,可以在字符串内和括号之间包含更多的数字和字母:

仅举几个例子

26U(35O40) will be read as 26 and (35 or 40)
22X(34U(42O27)) will be read as 22 xor (34 and (42 or 27))
21O(24U27) will be read as 21 or (24 and 27)
20X10X15 Will be read as 20 xor 10 xor 15
我已经读到,这可以通过使用平衡组来实现,但是我尝试了很多正则表达式,结果如下:

(?<ConditionId>\d+)(?<Operator>X|U|O)?(?<Open>\()(?<ConditionId>\d+)+(?<Operator>X|U|O)?(?<ConditionId>\d+)(?<-Open>\))
这就是为什么我不能将所有内容分组为“ConditionId”组和“Operator”组

编辑3 这也是一个有效的例子

(23X10)U(30O(20X19)
如果使用
(\d+[A-Z]*[()]?)+
它将在
22X(34U(42O27))
上返回一个匹配,并在
组[1]上捕获这些捕获。捕获

22X(
34U(
42O
27)

这提供了足够的信息来处理代码

20X10X15
上,相同的捕获组给出


20X
10X
15
假设您的输入已经有效,并且您想要解析它,这里有一个相当简单的正则表达式来实现:

(?:
    (?<ConditionId>\d+)
    |
    (?<Operator>[XUO])
    |
    (?<Open>\()
    |
    (?<Group-Open>\))
)+
(?)
(?\d+)
|
(?[XUO])
|
(?\()
|
(?\))
)+
-切换到“表”选项卡以查看所有捕获

该模式包含:

  • 将数字输入到
    $ConditionId
    组中
  • 操作员进入
    $Operator
  • 将括号中的子表达式放入
    $Group
    组(需要更好的名称吗?)。例如,对于字符串
    22X(34U(42O27))
    ,它将有两个捕获:
    42O27
    34U(42O27)
每个包含匹配字符串的位置。
$Group
及其包含的
$Operator
s、
$ConditionId
s和sub-
$Group
s之间的关系仅使用这些位置表示


(?)
当我们到达一个右括号时,会使用语法来捕获自相应的左括号之后的所有内容。这里将对此进行更详细的解释:

为什么您决定使用正则表达式来解决这个特定问题?您应该能够使用常规字符串操作和堆栈编写解析器。您好,感谢您的建议,我使用正则表达式是因为条件实际上比我在示例中使用的条件复杂一点,我认为正确的方法应该是使用正则表达式,因为有时候最难的就是最容易的,我不想最终与字符串操作发生冲突(有时候也会更难)。无论如何,你是对的,如果我不能用正则表达式解决问题,我肯定会看一看,因为这是我的第二个选择。你需要实际替换吗?不仅仅是提取字符串的一部分?
“22X(34U(42O27))”
=>
“22 xor(34和(42或27))”
你看,你将验证输入是否正确。但是如果可能的话,解释结果将非常困难。语言非常简单,只需手工编写解析器。见鬼,你可以编写一个相对简单的翻译程序来转换它,并使用Microsoft.CodeAnalysis.CSharp.Scripting像这样:
var expression=“26U(35O40)”.Replace(“U”,“和”).Replace(“O”,“|”).Replace(“X”,“|”);var值=(int)CSharpScript.EvaluateAsync(表达式).Result;
值得注意的是,在遵循这样的路径之前,您肯定需要确保该值是可信的,因为它将为您打开远程代码执行的大门。您好,感谢您提供详细的答案,但这是我一开始成功尝试的,问题是以后一切都会混淆。原因是我无法对条件或条件进行分组运算符是因为稍后我必须通过Id识别条件,并以输入中相同的方式针对其他条件应用运算符。
(23X10)U(30O(20X19)
(?:
    (?<ConditionId>\d+)
    |
    (?<Operator>[XUO])
    |
    (?<Open>\()
    |
    (?<Group-Open>\))
)+