【问题标题】:Generalized replacement by matching group id通过匹配组 id 进行广义替换
【发布时间】:2021-11-05 01:00:23
【问题描述】:

给定<digit>-<non-digit><non-digit>-<digit> 形式的字符串,我需要删除连字符(在Python 中)。 IE。 2-f 变为 2ff-2 变为 f2

到目前为止,我有(?:\d-\D)|(?:\D-\d),它找到了模式,但我想不出用空白替换连字符的方法。特别是:

  • 如果我sub上面的正则表达式,它将替换周围的字符(因为它们是匹配的);
  • 我可以使用(?:(\d)-(\D))|(?:(\D)-(\d)) 来明确捕获字符,然后sub\1\2 将正确处理2-f,将其转换为2f...但是!当然,它会失败f-2,因为这些字符位于第 3 组和第 4 组中,所以我们需要使用\3\4 进行替换。尝试为组命名失败,因为所有名称都必须是唯一的。

我知道我可以通过 2 个 sub 语句运行它,但有没有更优雅的解决方案?如果您知道自己在做什么,我知道正则表达式非常强大...谢谢!

【问题讨论】:

  • 一种解决方案是使用环视来断言数字/非数字字符存在而不匹配它们。你最终会得到类似(?<=\d)-(?=\D)|(?<=\D)-(?=\d)

标签: regex


【解决方案1】:

您可以在替换中使用\1\2 的替代方法,使用正则表达式PyPi modulebranch reset group (?| 结合使用,以便能够使用相同的组号进行交替。

(?|(\d)-(\D)|(\D)-(\d))

注意 \D 也可以匹配空格或换行符。如果要匹配数字以外的非空白字符,也可以使用[^\s\d] 而不是\D

查看Python demoregex demo

例如:

import regex

pattern = r"(?|(\d)-(\D)|(\D)-(\d))"
s = "2-f or f-2"

print(regex.sub(pattern, r"\1\2", s))

输出

2f or f2

【讨论】:

    【解决方案2】:

    没有什么可以阻止你替换为\1\2\3\4

    import re
    text = "2-f becomes 2f, f-2 becomes f2"
    print( re.sub(r"(\d)-(\D)|(\D)-(\d)", r"\1\2\3\4", text) )
    

    请参阅 regex demoPython demo

    这是可能的,因为所有指向未参与匹配的组的反向引用都使用以 Python 3.5 开头的空字符串进行初始化(以前,它们不是这样,这会导致问题,请参阅 Empty string instead of unmatched group error,您必须使用可调用对象作为替换参数)。

    当然,(?<=\d)-(?=\D)|(?<=\D)-(?=\d) 正则表达式,使用正向环视而不是捕获组,在当前场景中看起来更清晰,但如果边界模式是可变长度的,它将不起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-11
      • 2022-11-02
      • 1970-01-01
      • 2021-11-14
      • 1970-01-01
      • 2011-01-02
      • 1970-01-01
      相关资源
      最近更新 更多