当前位置: 首页 > 知识库问答 >
问题:

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

宓文斌
2023-03-14

当所有组都是可选的时,我在提取组时遇到了问题。

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

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

1: [A|B] [CD|DE|EF]-[1-1|1-2|2-2|2-3] [G|H]

但我希望用户打错字,或者不包含空格或其他东西。

所以我可以用绳子测试一下

A CD-1-1 G

并希望获得组

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

而且,对于测试字符串

DE-1-9 G

我想得到

  1. DE

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

[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”字符(可能存在或不存在)

问题是这与我期望的测试字符串组不匹配

A CD 1-9 G

我期望群体

    < li >答 < li >光盘 < li> < li>G

但我明白

  1. 一个
  2. 光盘

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

共有3个答案

酆俊远
2023-03-14

这看起来有点像验证,几乎所有内容都是可选的。
不过,你需要一些东西来帮助安排事情。

首先,主播^$.需要这个或其他一些伪锚(文本)来< br >给它一个开始和结束来聚焦搜索。

第二,数据部分之间的通用可选分隔符。这给了
一些可以使用的东西。空格和破折号可以用于[- ]

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

<代码>^(? =.)[- ]*([AB])?[- ]*(CD|DE|EF)?[- ]*(?:(1-[12]|2-[23])|\d-\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或长度

测试:

为了进行测试,我使用了多行模式,并将所有条目作为单个字符串包含在内
(如果您一次只检查一个输入,请不要使用此模式)。

输入:

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 
黄俊雄
2023-03-14

Regex101在Match 2中捕获G。尝试添加G全局修饰符。

梁丘招
2023-03-14

我建议使用

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

查看正则表达式演示

当然,要点是添加$锚-字符串结束断言,使字符串匹配到其末尾。

接下来,正如Paulo Almeida在评论中指出的,如果没有< code>1-1,那么一定有其他子模式与之匹配,比如说< code>1-9。因为在< code > CD /< code > de /< code > ef 之后可以是连字符或空格,所以让我们用[^ - ]匹配除空格或< code>-以外的0个字符。因为在< code > 1-1 /< code > 1-2 /< code > 2-2 /< code > 2-3 之后可以有一个空格,所以让我们匹配所有非空白字符。可以有更多这样的调整,但这就是如何编写工作正则表达式。

我还建议去掉单个字符的交替,把它们变成字符类。(?: *)? =*

 类似资料:
  • 我试图写一个正则表达式来匹配三个组,在三个组中,我希望有一个组是可选的。 正则表达式: 它匹配以下内容: 但是,不是在下面。 如何修改正则表达式,使其匹配两个组。如果第一条消息是三个组。 修复 测试 消息 如果是第二条消息,只有两组 < li >修复 < li >消息 消息

  • 我正在尝试匹配时间格式。时间可以用可选的小时、分钟和毫秒写入。唯一需要的值是秒。所以所有这些时间都写得正确,应该匹配。 我的正则表达式看起来像这样: 我希望每组对应正确的值。因此,组1应始终返回小时,组2应始终返回分钟,等等……我在Regex101中尝试了这一点,但正如您在这些结果中看到的,当没有小时时,组1总是优于组2。它与时间<code>11:12 如何确保每组始终对应正确的时间段?我可以以某

  • 我们得到了一些这样的内容:

  • 获取给定的URI,如下所示: 如何在斜线之间匹配捕获组中的每个角色?这可以通过以下方法完成: 这给了我三个组,其中: 我遇到的麻烦是让一个捕获组可选。我认为这将工作,认为我可以使每组可选(匹配零或更多): 有没有一种方法,可以使用Regex或PHP选择性地匹配上述URI的、或?

  • 有没有人试图描述与正则表达式匹配的正则表达式? 由于重复的关键字,这个主题几乎不可能在网上找到。 它可能在实际应用程序中不可用,因为支持正则表达式的语言通常具有解析它们的方法,我们可以将其用于验证,以及一种在代码中分隔正则表达式的方法,可用于搜索目的。 但是我仍然想知道匹配所有正则表达式的正则表达式是什么样子的。应该可以写一个。

  • 主要内容:基本模式匹配,字符簇,确定重复出现基本模式匹配 一切从最基本的开始。模式,是正则表达式最基本的元素,它们是一组描述字符串特征的字符。模式可以很简单,由普通的字符串组成,也可以非常复杂,往往用特殊的字符表示一个范围内的字符、重复出现,或表示上下文。例如: 这个模式包含一个特殊的字符 ^,表示该模式只匹配那些以 once 开头的字符串。例如该模式与字符串 "once upon a time" 匹配,与 "There once was