在Python中使用re.sub获取匹配的组内容

8
在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'

1
我不确定是否可能(至少同时进行),因为re.sub的返回对象是一个字符串。如果你有这样的东西rx_obj = re.search('123$', another_string),你会得到一个可以被rx_obj.group()捕获的RE对象。 - Revan
你猜想可能是对的,同时做这两件事情似乎不可能。其他方法看起来有点取巧或者基本上是两个分开的步骤。 - KT8
1
请注意,在Perl中使用特殊的编号变量之前,您应始终验证匹配是否成功: if ($str =~ s/(\d+)//){ $x = $1; } - stevieb
3个回答

16

你可以通过将函数传递给 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] - Erisan Olasheni

2
你可以做以下事情:
sub_str = re.search("(\d+)", str).group(1)

将找到 "123" 部分。

然后替换它:

str = str.replace(sub_str, "")

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


1
这个答案是不正确的,至少不够通用 - 你不能假设找到 sub_str 作为一个字符串就相当于找到原始模式作为一个正则表达式。例如,如果模式是 r"foo(?!bar)",它只会在位置6匹配 "foobarfoo",但匹配的字符串 "foo" 出现在位置0和6。 - Ken Williams

-3

以下代码已在Python 3.6下测试通过。

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

123

1
这并没有回答问题 - 它只是碰巧返回与\1相同的字符串,因为你的替换模式是r'\1' - Ken Williams

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接