正则表达式和平衡组
Regex and 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 xor 15
我读到这可以使用平衡组获得,但是我尝试了很多正则表达式,结果如下:
(?<ConditionId>\d+)(?<Operator>X|U|O)?(?<Open>\()(?<ConditionId>\d+)+(?<Operator>X|U|O)?(?<ConditionId>\d+)(?<-Open>\))
我也想过,也许我让它变得更难了,我应该 运行 多次使用相同的正则表达式,第一次是括号外的所有内容,第二次是括号内的内容和 运行 匹配内部时再次使用它。类似的东西:
(?<ConditionId>\d+)?(?<Operator>U|O|X)?(?<Inner>(?:\().*(?:\)))
建议或帮助?
提前致谢。
编辑 1:我不必验证输入,只需对其进行解析。
编辑 2:因此,背后的原因是通过条件 Id 识别条件,然后针对输入字符串中的其他条件应用运算符。按照与输入字符串中出现的顺序相同的顺序,一个更容易理解的更一般的例子是逻辑门:
对于给定的 20x10x15 输入,我将必须通过 conditionId 识别条件并检查条件是否有效并对它们应用 XOR 运算符,例如:
true X true X false = false;
false X false X true = true;
true X (false U true) = true
这就是我无法将所有内容分为 "ConditionId" 组和 "Operator" 组的原因。
编辑 3
这也是一个有效的例子
(23X10)U(30O(20X19)
如果您使用 (\d+[A-Z]*[()]?)+
,它将 return 在 22X(34U(42O27))
上与这些捕获在 Groups[1].Captures
上匹配
22X(
34U(
42O
和
27)
这提供了足够的信息来处理代码。
在 20X10X15
上,同一个捕获组给出
20X
10X
和 15
假设您的输入已经有效,并且您想解析它,这里有一个相当简单的正则表达式来实现:
(?:
(?<ConditionId>\d+)
|
(?<Operator>[XUO])
|
(?<Open>\()
|
(?<Group-Open>\))
)+
Working example - Regex Storm - 切换到 table 选项卡以查看所有捕获。
模式捕获:
- 号码进入
$ConditionId
组。
- 运算符进入
$Operator
组。
- 括号中的子表达式进入
$Group
组(需要更好的名称?)。例如,对于字符串 22X(34U(42O27))
,它将有两个捕获:42O27
和 34U(42O27)
.
每个 capture 包含匹配字符串的位置。 $Group
和它包含的$Operator
、$ConditionId
和子$Group
之间的关系只用这些位置来表示。
(?<Group-Open>)
语法用于当我们到达右括号时 捕获 从相应的左括号开始的所有内容。这里有更详细的解释:What are regular expression 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 xor 15
我读到这可以使用平衡组获得,但是我尝试了很多正则表达式,结果如下:
(?<ConditionId>\d+)(?<Operator>X|U|O)?(?<Open>\()(?<ConditionId>\d+)+(?<Operator>X|U|O)?(?<ConditionId>\d+)(?<-Open>\))
我也想过,也许我让它变得更难了,我应该 运行 多次使用相同的正则表达式,第一次是括号外的所有内容,第二次是括号内的内容和 运行 匹配内部时再次使用它。类似的东西:
(?<ConditionId>\d+)?(?<Operator>U|O|X)?(?<Inner>(?:\().*(?:\)))
建议或帮助?
提前致谢。
编辑 1:我不必验证输入,只需对其进行解析。
编辑 2:因此,背后的原因是通过条件 Id 识别条件,然后针对输入字符串中的其他条件应用运算符。按照与输入字符串中出现的顺序相同的顺序,一个更容易理解的更一般的例子是逻辑门:
对于给定的 20x10x15 输入,我将必须通过 conditionId 识别条件并检查条件是否有效并对它们应用 XOR 运算符,例如:
true X true X false = false;
false X false X true = true;
true X (false U true) = true
这就是我无法将所有内容分为 "ConditionId" 组和 "Operator" 组的原因。
编辑 3 这也是一个有效的例子
(23X10)U(30O(20X19)
如果您使用 (\d+[A-Z]*[()]?)+
,它将 return 在 22X(34U(42O27))
上与这些捕获在 Groups[1].Captures
22X(
34U(
42O
和
27)
这提供了足够的信息来处理代码。
在 20X10X15
上,同一个捕获组给出
20X
10X
和 15
假设您的输入已经有效,并且您想解析它,这里有一个相当简单的正则表达式来实现:
(?:
(?<ConditionId>\d+)
|
(?<Operator>[XUO])
|
(?<Open>\()
|
(?<Group-Open>\))
)+
Working example - Regex Storm - 切换到 table 选项卡以查看所有捕获。
模式捕获:
- 号码进入
$ConditionId
组。 - 运算符进入
$Operator
组。 - 括号中的子表达式进入
$Group
组(需要更好的名称?)。例如,对于字符串22X(34U(42O27))
,它将有两个捕获:42O27
和34U(42O27)
.
每个 capture 包含匹配字符串的位置。 $Group
和它包含的$Operator
、$ConditionId
和子$Group
之间的关系只用这些位置来表示。
(?<Group-Open>)
语法用于当我们到达右括号时 捕获 从相应的左括号开始的所有内容。这里有更详细的解释:What are regular expression Balancing Groups?