捕获组之前或捕获组之后的正则表达式,具有单个捕获组

Posted

技术标签:

【中文标题】捕获组之前或捕获组之后的正则表达式,具有单个捕获组【英文标题】: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?)必须为真

【问题讨论】:

【参考方案1】:

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

改变逻辑呢?

试试

^\d4[ _].*?[_:](\d+)

见proof。

说明

--------------------------------------------------------------------------------
  ^                        the beginning of the string
--------------------------------------------------------------------------------
  \d4                    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]

【讨论】:

以上是关于捕获组之前或捕获组之后的正则表达式,具有单个捕获组的主要内容,如果未能解决你的问题,请参考以下文章

具有多个捕获组的 R 中的正则表达式组捕获

正则表达式:捕获重复捕获组的所有单个实例 [重复]

正则表达式:如何在捕获单个组时匹配整个字符串 [重复]

Java 正则表达式之捕获组

具有捕获组的有效正则表达式,但 sed 脚本不起作用

将排除捕获组的正则表达式