首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >正则表达式匹配和所有可选组

正则表达式匹配和所有可选组
EN

Stack Overflow用户
提问于 2016-04-02 18:38:01
回答 3查看 130关注 0票数 2

当所有的小组都可能是可选的时候,我很难把它们提取出来。

上下文(如果您愿意的话跳到末尾):--这是在将字符串与一组正则表达式进行最佳匹配的上下文中,并查看哪个表达式具有最多的组匹配。

例如,我可能有一个潜在的格式;

代码语言:javascript
运行
复制
1: [A|B] [CD|DE|EF]-[1-1|1-2|2-2|2-3] [G|H]

但我希望用户输入错误,或不包括空格或其他东西。

所以我可以用字符串来测试它

代码语言:javascript
运行
复制
A CD-1-1 G

想找个小组

  1. 一个
  2. 光盘
  3. 1-1
  4. G

但是,对于测试字符串

代码语言:javascript
运行
复制
DE-1-9 G

我想要

  1. DE
  2. G

,下面是匹配以下可选组的正则表达式:

代码语言:javascript
运行
复制
[A|B] [CD|DE|EF]-[1-1|1-2|2-2|2-3] [G|H]

Regex:

代码语言:javascript
运行
复制
(A|B)?(?: *)?(CD|DE|EF)?(?:-|(?: ))?((?:1-(?:1|2))|(?:2-(?:2|3)))?(?: *)?(G|H)?

详细说明我认为这应该如何运作;

  • (A)\x{e76f}-匹配"A“或"B”字符(可能在那里,也可以不在那里)。
  • (?:*)?-匹配一些空格字符(这些字符可能也不存在),但不需要组。
  • ?-匹配"CD“"DE”或"EF“(可能在也可能不在那里)。
  • (?:
  • (?:(?:1-(?:1 x=2)\x{e76f}(?:2-(?:2-(?:2=3)?-匹配[1-1\2]或2-[2/3]
  • (?:*)?-匹配一些空格字符(这些字符可能也不存在),但不需要组。
  • (G\H)?-匹配"G“或"H”字符(该字符可能在那里,也可以不存在)。

与测试字符串不匹配的问题

代码语言:javascript
运行
复制
A CD 1-9 G

我希望大家

  1. 一个
  2. 光盘
  3. G

但我得到

  1. 一个
  2. 光盘

为什么在第三组之后不匹配呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-04-02 19:56:16

我建议用

代码语言:javascript
运行
复制
^([AB]?) *(?:(CD|DE|EF)?|[^- ]*)[- ]?(?:(1-[12]|2-[23])?|\S*) *([GH]?)$

regex演示

当然,要点是添加$锚端字符串断言,使字符串匹配到它的末尾。

接下来,正如保罗·阿尔梅达所指出的,在评论中,如果没有1-1,就必须有一些其他子模式来匹配,比如1-9。因为在CD / DE / EF之后可以是连字符或空格,所以让我们用[^ - ]来匹配0+字符(而不是空格或- )。因为在1-1 / 1-2 / 2-2 / 2-3之后可以有一个空格,所以让我们匹配所有非空格字符。可以进行更多这样的调整,但这就是编写工作正则表达式的方法。

我还建议消除与单个字符的交替,并将它们转换为字符类。(?: *)? = *

票数 0
EN

Stack Overflow用户

发布于 2016-04-02 18:42:52

Regex101在匹配2中捕获G。尝试添加global修饰符。

票数 0
EN

Stack Overflow用户

发布于 2016-04-03 00:52:29

这看起来有点像验证,几乎所有的东西都是可选的。

尽管如此,你还是需要一些东西来帮你把事情弄清楚。

首先,锚定^$。这或其他一些伪锚(文本)是需要的。

给它一个开始和结束,集中搜索。

第二,数据部分之间的通用可选分隔符。这给了我们

这是可以消费的东西。[- ]可以使用空格和破折号。

这将使零件从左到右排列。它们都是可选的。

^(?=.)[- ]*([AB])?[- ]*(CD|DE|EF)?[- ]*(?:(1-[12]|2-[23])|\d-\d)?[- ]*([GH])?[- ]*$

对此有一些解释:

代码语言:javascript
运行
复制
 ^                             # 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或length>0,取决于引擎)。

测试:

为了进行测试,我使用了多行模式,并将所有条目作为一个单独的条目包括在内。

字符串(如果一次只检查一个输入,则不要使用此模式)。

输入:

代码语言:javascript
运行
复制
A CD 1-9 G
DE-1-9 G
A CD-1-1 G
AG
4-8

输出:

代码语言:javascript
运行
复制
 **  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 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36377299

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档