Python 如何在re中替换多个图案

Python 如何在re中替换多个图案,python,regex,string,Python,Regex,String,我有以下字符串: a = 'P/2008 A3 (SOHO)' 我想将其更改为: a = 'P/2008-A3-SOHO' 尝试解决问题: 步骤1: b = re.sub("\s", "-", a) print b 输出: P/2008-A3-(SOHO) P/2008-A3-SOHO 步骤2: c = re.sub("[\(\)]", "", b) print c 输出: P/2008-A3-(SOHO) P/2008-A3-SOHO 我得到了我需要的输出,但是有更有效的方法吗

我有以下字符串:

a = 'P/2008 A3 (SOHO)'
我想将其更改为:

a = 'P/2008-A3-SOHO'
尝试解决问题:

步骤1:

b = re.sub("\s", "-", a)
print b
输出:

P/2008-A3-(SOHO)
P/2008-A3-SOHO
步骤2:

c = re.sub("[\(\)]", "", b)
print c
输出:

P/2008-A3-(SOHO)
P/2008-A3-SOHO
我得到了我需要的输出,但是有更有效的方法吗?我想在一个步骤中解决它。

不仅接受第二个参数的字符串,而且还接受函数。函数获取匹配对象作为参数,函数的返回值用作替换字符串:

>>> re.sub(r"[()\s]", lambda m: '-' if m.group().isspace() else '', a)
'P/2008-A3-SOHO'
\1-\2-\3
顺便说一句,您不需要在字符类[…]内转义。

您可以使用捕获组从输入中捕获特定字符串

正则表达式:

^(\S+)\s*(\S+)\s*\(([^)]*)\)$
替换字符串:

>>> re.sub(r"[()\s]", lambda m: '-' if m.group().isspace() else '', a)
'P/2008-A3-SOHO'
\1-\2-\3

falsetru提供了一个很好的答案,即如何在一个正则表达式操作中进行多次替换

我只想指出,出于可读性和效率的考虑,一行程序并不总是更好。两个正则表达式比一个带有lambda回调的正则表达式更快,我认为它们也更可读:

>>> import timeit
>>> setup = "import re; a = 'P/2008 A3 (SOHO) P/2008 A3 (SOHO)'"
>>> stmt1 = """re.sub(r"[()\s]", lambda m: '-' if m.group().isspace() else '', a)"""
>>> stmt1 = """r = re.sub(r"[()\s]", lambda m: '-' if m.group().isspace() else '', a)"""
>>> stmt2 = """r = re.sub("\s", "-", a)
... r = re.sub("[\(\)]", "", r)"""
>>> timeit.timeit(setup=setup, stmt=stmt1)
9.311270136909659
>>> timeit.timeit(setup=setup, stmt=stmt2)
7.7278099642134315
当我们编译正则表达式时,这一点变得更加明显,为了公平起见,我们事先定义了一个函数而不是lambda:

>>> setup = """import re
... a = 'P/2008 A3 (SOHO) P/2008 A3 (SOHO)'
... r1 = re.compile(r"[()\s]")
... r2 = re.compile(r"\s")
... r3 = re.compile(r"[()]")
... def f(m): return '-' if m.group().isspace() else ''
... """
>>> stmt1 = """r = r1.sub(f, a)"""
>>> timeit.timeit(setup=setup, stmt=stmt1)
7.351804295542024
>>> stmt2 = """r = r2.sub("-", a)
... r = r3.sub("", r)"""
>>> timeit.timeit(setup=setup, stmt=stmt2)
4.5631406412521756

@falsetru代码可以工作,但是我想了解lambda函数是如何工作的。你能提供一些细节吗?谢谢:@user3097391,函数接收。匹配对象有一个,当在没有参数的情况下调用时,返回一个匹配的字符串。@user3097391,X如果。。。else Y是一个条件表达式。+1表示正则表达式中的lambdas替换,即C中的委托,JS、Perl和PHP中的匿名函数,Ruby中的块: