【问题标题】:Get Group Match in re.sub in Python在 Python 中的 re.sub 中获取组匹配
【发布时间】:2016-03-24 08:40:39
【问题描述】:

在 Perl 中,我可以同时进行替换和捕获组匹配。例如

my $string = "abcdef123";
$string =~ s/(\d+)//;
my $groupMatched = $1; # $groupMatched is 123

在 Python 中,我可以使用 re.sub 函数进行替换,如下所示。但是,如果不调用另一个函数 re.match 并执行附加操作,我找不到捕获 \d+ 组匹配的方法。

string = "abcdef123"
string = re.sub("(\d+)", "", string)

有谁知道我如何从同一个 re.sub 操作中捕获“\d+”匹配值作为单独的变量?我尝试了以下命令,但它不起作用。

print r'\1'

【问题讨论】:

  • 我不确定这是否可能(至少同时),因为re.sub 的返回对象是一个字符串。如果你有类似rx_obj = re.search('123$', another_string) 的东西,你会得到一个可以被rx_obj.group() 捕获的 RE 对象。
  • 猜你可能是对的,不可能同时做这两个。其他方法似乎有点骇人听闻,或者基本上是两个独立的步骤。
  • 请注意,在 Perl 中,您应该始终在使用特殊编号的变量之前验证匹配是否成功:if ($str =~ s/(\d+)//){ $x = $1; }

标签: python regex perl


【解决方案1】:

您可以作弊并将函数传递给re.sub

results = []
def capture_and_kill(match):
    results.append(match)
    return ""
string = "abcdef123"
string = re.sub("(\d+)", capture_and_kill, string)
results[0].group(1)
# => '123'

【讨论】:

  • results[0].group()[1]
【解决方案2】:

您可以执行以下操作:

sub_str = re.search("(\d+)", str).group(1)

会找到“123”部分。

然后你替换它:

str = str.replace(sub_str, "")

请注意,如果您有超过 [0-9] 的序列,则需要使用 findall 并手动迭代所有匹配项。

【讨论】:

  • 这个答案是不正确的,或者至少不是很笼统 - 您不能假设将 sub_str 作为字符串查找与将原始模式作为正则表达式查找相同。例如,如果模式为r"foo(?!bar)",它将仅在位置6 匹配"foobarfoo",但匹配的字符串"foo" 出现在位置0 和6。
【解决方案3】:

以下代码在 python 3.6 下测试。

test = "abcdef123"
resp = re.sub(r'\w+[A-Za-z](\d+)',r'\1',test)
print (resp)

123

【讨论】:

  • 这并不能回答问题 - 它恰好返回与 \1 相同的字符串,因为您的替换模式是 r'\1'
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-15
  • 2019-05-16
  • 2015-12-18
  • 2016-05-23
相关资源
最近更新 更多