【问题标题】:Regex before capture group OR after capture group, with single capture group捕获组之前或捕获组之后的正则表达式,具有单个捕获组
【发布时间】:2020-10-30 12:22:42
【问题描述】:

在 BigQuery 中,我只能有一个捕获组。

这个正则表达式实现了这一点,但有两个捕获组。

[^a-zA-Z]([0-9]+)s[^a-zA-Z]|:([0-9]+)[^a-zA-Z]

示例字符串:

2013_some_text | :05 | even more text  (12345)  # Extract 05
2018 some_text_06s-more text (2343)             # Extract 06

我如何重写这个正则表达式以拥有一个捕获组,它检查是否有前缀冒号 : 或后缀 s

例如像

[^a-zA-Z]:?([0-9]+)s?[^a-zA-Z] 但两者之一(:?s?)必须为真

【问题讨论】:

    标签: regex google-bigquery


    【解决方案1】:

    这里似乎无法使用单个捕获组。

    改变逻辑呢?

    试试

    ^\d{4}[ _].*?[_:](\d+)
    

    proof

    说明

    --------------------------------------------------------------------------------
      ^                        the beginning of the string
    --------------------------------------------------------------------------------
      \d{4}                    digits (0-9) (4 times)
    --------------------------------------------------------------------------------
      [ _]                     any character of: ' ', '_'
    --------------------------------------------------------------------------------
      .*?                      any character except \n (0 or more times
                               (matching the least amount possible))
    --------------------------------------------------------------------------------
      [_:]                     any character of: '_', ':'
    --------------------------------------------------------------------------------
      (                        group and capture to \1:
    --------------------------------------------------------------------------------
        \d+                      digits (0-9) (1 or more times (matching
                                 the most amount possible))
    --------------------------------------------------------------------------------
      )                        end of \1
    

    【讨论】:

    • 引用问题 - :? [之前] 或 s? [之后] 两者之一必须为真 - 所以上述解决方案不能解决第二部分!
    • @MikhailBerlyant 关键是它按预期提取了0506
    • 不!关键是要遵循提取的逻辑! :o)
    • @MikhailBerlyant 否,如果无法使用所需工具表达逻辑。逻辑必须改变。
    • 在这种情况下select '05' union all select '06'也可以是一个解决方案???仅仅因为它恰好为您提供了特定样本的预期输出?
    【解决方案2】:
    import re
    a = '2013_some_text | :05 | even more text  (12345)'
    b = '2018 some_text_06s-more text (2343)'
    c = ':07s'
    d = '07'
    
    r1 = re.compile(r'(?:(?<=:(?=\d\d(?!\w)))|(?<!:)(?=\d\ds))(.{2})')
    r2 = re.compile(r'(?:(?=:\d\d(?!\w))|(?<!:)(?=\d\ds))(.{3})')
    
    a_r1 = r1.search(a).groups()
    b_r1 = r1.search(b).groups()
    
    a_r2 = r2.search(a).groups()
    b_r2 = r2.search(b).groups()
    
    #error NoneType
    #c_r1 = r1.search(c).groups()
    #d_r1 = r1.search(d).groups()
    #c_r2 = r2.search(c).groups()
    #d_r2 = r2.search(d).groups()
    
    
    print('%-4s: %s\n%-4s: %s\n\n%-4s: %s\n%-4s: %s' % 
         ('a_r1', a_r1, 'b_r1', b_r1, 'a_r2', a_r2, 'b_r2', b_r2))
    
    a_r1: ('05',)
    b_r1: ('06',)
    
    a_r2: (':05',)
    b_r2: ('06s',)
    [Finished in 0.4s]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-31
      • 2023-03-15
      • 2015-07-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多