【问题标题】:regex to grab text if code exists如果代码存在,正则表达式抓取文本
【发布时间】:2016-03-01 21:52:33
【问题描述】:

如果代号存在,我正在尝试构建一个正则表达式来添加代码值

举个例子:

{(en56), (sc45), (da77), (cd29)}
{(en56), (sc45), (cd29)}

我会写一个正则表达式 {[(]en(?<en>\d{2}).*[(]sc(?<sc>\d{2}).*[(]da(?<da>\d{2}).*[(]cd(?<cd>\d{2}).*

无论如何我都会抓住第一行,因为它匹配并且将提取标记的结果。如果输入没有它,如何将da 保留为可选。

当我尝试使用 ? 时,它基本上消除了第一个结果中的值 {[(]en(?<en>\d{2}).*[(]sc(?<sc>\d{2}).*([(]da(?<da>\d{2}))?.*[(]cd(?<cd>\d{2}).*

【问题讨论】:

  • 真的是Qt吗?
  • 我添加了一个新的答案,看看。
  • 谢谢guyz .. 我的分隔线有问题,这是大表达的一部分。所以我不能使用@sln 答案。我使用了 wictor's 并稍作调整。
  • 我的新答案有所不同,因为它可以执行您最初想要的操作,只是它是任意匹配,使其成为一种更强大的匹配方式。您以前可能没有见过该技术,您应该尝试一下。例如,查看我发布的答案中的匹配结果。\

标签: regex regex-greedy


【解决方案1】:

您可以通过将正则表达式的该部分包含在带有? 量词的non-capturing group 中来使其成为可选部分,该量词与它所量化的子模式的一次或零次匹配:

{[(]en(?<en>\d{2}).*[(]sc(?<sc>\d{2})(?:.*[(]da(?<da>\d{2}))?.*[(]cd(?<cd>\d{2}).*
                                     ^^^                   ^^

regex demo

使用这种技术,您可以在必要时将正则表达式的更多部分设为可选。

【讨论】:

  • 在 Qt 中,您必须使用双反斜杠。
【解决方案2】:

新答案

我刚刚注意到您正在使用 Qt 正则表达式。
由于 Qt 使用 PCRE 引擎,您可以利用条件
不仅可以选择性地查找项目,而且还可以找到它们乱序
无论它们是否按顺序排列,它仍然会找到它们。

所以,所有的基础都被覆盖了。你会看到一些高级的
正则表达式技术。

这个想法是找到 1-4 个项目。这是通过组构造和
范围量词(?: ... | ... | ... | ...){1,4}

范围上限 4 因为那是组中的项目数。

最后,每个项目都保护有一个条件以确保
项目不会再次匹配。这是确保上限4
所必需的 指的是唯一的项目,而 范围 使每个项目都是可选的。

这样做的好处是每个项目都可以匹配乱序
这意味着它在源文本中出现的项目顺序
无关紧要。

祝你好运!并希望您有机会尝试一下..

Formatted and tested:

 #  {(?:.*?(?:(?(<en>)(?!))[(]en(?<en>\d{2})|(?(<sc>)(?!))[(]sc(?<sc>\d{2})|(?(<da>)(?!))[(]da(?<da>\d{2})|(?(<cd>)(?!))[(]cd(?<cd>\d{2}))){1,4}

 # Match 1-4 'Out-Of-Order' unique items
 # --------------------------------------------
 {
 (?:                  # Cluster start - loop to find out of order items
      .*? 
      (?:
           (?(<en>)             # Condition, not matched 'en' before
                (?!)
           )
           [(] en
           (?<en> \d{2} )       # (1)
        |                     # or,
           (?(<sc>)             # Condition, not matched 'sc' before
                (?!)
           )
           [(] sc
           (?<sc> \d{2} )       # (2)
        |                     # or,
           (?(<da>)             # Condition, not matched 'da' before
                (?!)
           )
           [(] da
           (?<da> \d{2} )       # (3)
        |                     # or,
           (?(<cd>)             # Condition, not matched 'cd' before
                (?!)
           )
           [(] cd
           (?<cd> \d{2} )       # (4)
      )
 ){1,4}               # Cluster end - find  1 to 4 unique items

测试输入

{(sc45), (en56), (da77), (cd29)}
{(da77), (cd29)}
{(en56), (sc45), (cd29)}
{(da77), (cd29) (en56), (sc45)}
{(sc45)}
{(en56), (cd29), (sc45)}

输出

 **  Grp 0      -  ( pos 0 , len 30 ) 
{(sc45), (en56), (da77), (cd29  
 **  Grp 1 [en] -  ( pos 12 , len 2 ) 
56  
 **  Grp 2 [sc] -  ( pos 4 , len 2 ) 
45  
 **  Grp 3 [da] -  ( pos 20 , len 2 ) 
77  
 **  Grp 4 [cd] -  ( pos 28 , len 2 ) 
29
------------  
 **  Grp 0      -  ( pos 34 , len 14 ) 
{(da77), (cd29  
 **  Grp 1 [en] -  NULL 
 **  Grp 2 [sc] -  NULL 
 **  Grp 3 [da] -  ( pos 38 , len 2 ) 
77  
 **  Grp 4 [cd] -  ( pos 46 , len 2 ) 
29  
------------  
 **  Grp 0      -  ( pos 52 , len 22 ) 
{(en56), (sc45), (cd29  
 **  Grp 1 [en] -  ( pos 56 , len 2 ) 
56  
 **  Grp 2 [sc] -  ( pos 64 , len 2 ) 
45  
 **  Grp 3 [da] -  NULL 
 **  Grp 4 [cd] -  ( pos 72 , len 2 ) 
29  
------------  
 **  Grp 0      -  ( pos 78 , len 29 ) 
{(da77), (cd29) (en56), (sc45  
 **  Grp 1 [en] -  ( pos 97 , len 2 ) 
56  
 **  Grp 2 [sc] -  ( pos 105 , len 2 ) 
45  
 **  Grp 3 [da] -  ( pos 82 , len 2 ) 
77  
 **  Grp 4 [cd] -  ( pos 90 , len 2 ) 
29  
------------  
 **  Grp 0      -  ( pos 111 , len 6 ) 
{(sc45  
 **  Grp 1 [en] -  NULL 
 **  Grp 2 [sc] -  ( pos 115 , len 2 ) 
45  
 **  Grp 3 [da] -  NULL 
 **  Grp 4 [cd] -  NULL 
------------  
 **  Grp 0      -  ( pos 121 , len 22 ) 
{(en56), (cd29), (sc45  
 **  Grp 1 [en] -  ( pos 125 , len 2 ) 
56  
 **  Grp 2 [sc] -  ( pos 141 , len 2 ) 
45  
 **  Grp 3 [da] -  NULL 
 **  Grp 4 [cd] -  ( pos 133 , len 2 ) 
29  

基准测试

Regex1:   {(?:.*?(?:(?(<en>)(?!))[(]en(?<en>\d{2})|(?(<sc>)(?!))[(]sc(?<sc>\d{2})|(?(<da>)(?!))[(]da(?<da>\d{2})|(?(<cd>)(?!))[(]cd(?<cd>\d{2}))){1,4}
Options:  < none >
Completed iterations:   50  /  50     ( x 1000 )
Matches found per iteration:   6
Elapsed Time:    3.41 s,   3411.71 ms,   3411714 µs

【讨论】:

    猜你喜欢
    • 2014-02-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 2019-11-28
    • 2013-01-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多