Regex 正则表达式匹配和所有可选组
我在提取组时遇到问题,因为所有组都可能是可选的Regex 正则表达式匹配和所有可选组,regex,Regex,我在提取组时遇到问题,因为所有组都可能是可选的 上下文(如果愿意,请跳到结尾): 这是在一个字符串与一组正则表达式最佳匹配的上下文中,并查看哪个表达式具有最多的组匹配 例如,我可能有一个潜在的格式 1: [A|B] [CD|DE|EF]-[1-1|1-2|2-2|2-3] [G|H] 但我希望用户输入错误,或者不包含空格或其他内容 所以我可以用字符串来测试它 A CD-1-1 G 并且想要得到团体 A 光盘 1-1 G 而且,对于测试字符串 DE-1-9 G A CD 1-9 G 我想
上下文(如果愿意,请跳到结尾): 这是在一个字符串与一组正则表达式最佳匹配的上下文中,并查看哪个表达式具有最多的组匹配 例如,我可能有一个潜在的格式
1: [A|B] [CD|DE|EF]-[1-1|1-2|2-2|2-3] [G|H]
但我希望用户输入错误,或者不包含空格或其他内容
所以我可以用字符串来测试它
A CD-1-1 G
并且想要得到团体
DE-1-9 G
A CD 1-9 G
我想买一个
这是我的正则表达式,用于匹配以下可选组
[A|B] [CD|DE|EF]-[1-1|1-2|2-2|2-3] [G|H]
正则表达式:
(A|B)?(?: *)?(CD|DE|EF)?(?:-|(?: ))?((?:1-(?:1|2))|(?:2-(?:2|3)))?(?: *)?(G|H)?
分解我认为应该如何工作
- (A | B)—匹配“A”或“B”字符(可能存在也可能不存在)
- (?:*)?-匹配一些空格字符(也可能不存在),但不需要组
- (CD|DE|EF)?-匹配“CD”、“DE”或“EF”(可能存在也可能不存在)
- (?:-|(?:)?-匹配“-”或某些空格(可能有也可能没有)
- ((?:1-(?:1 | 2))|(?:2-(?:2 | 3)))-匹配[1-[1 | 2]]或[2-[2 | 3]](可能正确,也可能不正确/完全正确)
- (?:*)?-匹配一些空格字符(也可能不存在),但不需要组
- (G | H)—匹配“G”或“H”字符(可能存在也可能不存在)
DE-1-9 G
A CD 1-9 G
我期待着团体
为什么在第三组之后不匹配?Regex101捕捉匹配2中的
G
。尝试添加g
lobal修饰符。我建议使用
^([AB]?) *(?:(CD|DE|EF)?|[^- ]*)[- ]?(?:(1-[12]|2-[23])?|\S*) *([GH]?)$
见
当然,主要的一点是添加$
锚定-字符串结束断言,使字符串匹配到其结束
接下来,正如所指出的,如果没有1-1
,则必须有其他子模式来匹配,例如1-9
。由于CD
/DE
/EF
之后可以是连字符或空格,因此让我们将空格或-
以外的0+字符与[^-]
匹配。由于1-1
/1-2
/2-2
/2-3
后面可能有空格,所以让我们匹配所有非空白字符。可以有更多这样的调整,但这就是工作正则表达式的编写方式
我还建议去掉单个字符的交替,并将它们转换为字符类<代码>(?:*)?=
*
这看起来有点像验证,几乎所有内容都是可选的。不过,你还是需要一些东西来帮助你把事情安排好 首先,锚定
^$
。需要此或其他一些伪锚(文本)给它一个开始和结束,以集中搜索 第二,数据部分之间的公共可选分隔符。这就产生了
它是一种消费品。可以使用空格和破折号
[-]
这将从左到右排列零件。它们都是可选的
^(?=)[-]*([AB])?[-]*(CD | DE | EF)?[-]*(?:(1-[12]| 2-[23])\d-[-]*([GH])?[-]*$
下面是一些解释:
^ # Beginning of string
(?= . ) # Only used to insure not a blank line
[- ]* # Optional specific delimiters
( [AB] )? # (1), Optional A or B
[- ]* # Optional specific delimiters
( CD | DE | EF )? # (2), Optional CD or DE or EF
[- ]* # Optional specific delimiters
(?: # Optional numb-numb
( 1- [12] | 2- [23] ) # (3), Only ones we care about
| # or,
\d - \d # Any numb-numb
)?
[- ]* # Optional specific delimiters
( [GH] )? # (4), Optional G or H
[- ]* # Optional specific delimiters
$ # End of string
所有捕获组都设置为可选(而不是其内容),因此这会使很容易测试它们是否有数据(NULL或长度>0,取决于引擎) 测试: 为了进行测试,我使用了多行模式,并将所有条目作为一个单独的条目包含进来
字符串(如果一次只检查一个输入,请不要使用此模式) 输入:
A CD 1-9 G
DE-1-9 G
A CD-1-1 G
AG
4-8
输出:
** Grp 0 - ( pos 0 , len 10 )
A CD 1-9 G
** Grp 1 - ( pos 0 , len 1 )
A
** Grp 2 - ( pos 2 , len 2 )
CD
** Grp 3 - NULL
** Grp 4 - ( pos 9 , len 1 )
G
-----------
** Grp 0 - ( pos 12 , len 8 )
DE-1-9 G
** Grp 1 - NULL
** Grp 2 - ( pos 12 , len 2 )
DE
** Grp 3 - NULL
** Grp 4 - ( pos 19 , len 1 )
G
-----------
** Grp 0 - ( pos 22 , len 10 )
A CD-1-1 G
** Grp 1 - ( pos 22 , len 1 )
A
** Grp 2 - ( pos 24 , len 2 )
CD
** Grp 3 - ( pos 27 , len 3 )
1-1
** Grp 4 - ( pos 31 , len 1 )
G
-----------
** Grp 0 - ( pos 34 , len 2 )
AG
** Grp 1 - ( pos 34 , len 1 )
A
** Grp 2 - NULL
** Grp 3 - NULL
** Grp 4 - ( pos 35 , len 1 )
G
-----------
** Grp 0 - ( pos 38 , len 3 )
4-8
** Grp 1 - NULL
** Grp 2 - NULL
** Grp 3 - NULL
** Grp 4 - NULL
我认为Wiktor的模式是可行的,为了回答你的问题,可以选择使用
[1-1 | 1-2 | 2-2 | 2-3]
,但是只有在没有任何东西的情况下,'G'才会匹配。1-9
会破坏模式。Wiktor通过在每个中心模式中允许一个空的替代方案来解决这个问题。这是另一个很好的答案。谢谢你看了。@THRND-没问题。这是一个20美元的答案,因为它提供了一种可以垂直应用的技术。快速的$2答案就像,一次性的,使用一次就不能再使用。。