代码之家  ›  专栏  ›  技术社区  ›  GM.

如果存在代码,则使用regex获取文本

  •  2
  • GM.  · 技术社区  · 8 年前

    我正在尝试构建一个正则表达式,以在存在代码名的情况下添加代码值

    举个例子:

    {(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}).*

    2 回复  |  直到 8 年前
        1
  •  2
  •   Wiktor Stribiżew    8 年前

    您可以通过将正则表达式的该部分封装到 non-capturing group 用一个 ? 与它所量化的子模式的一次或零次匹配的量词:

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

    看见 regex demo

    如果需要,可以使用此技术使正则表达式的更多部分成为可选的。

        2
  •  1
  •   user557597 user557597    8 年前

    新答案

    我刚刚注意到你在使用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