我正在处理长字符串,我需要用''
替换相邻句号.
和/或冒号:
的所有组合,但仅限于它们不相邻时到任何空白。例子:
a.bcd
应该abcd
a..::.:::.:bcde.....:fg
应该abcdefg
a.b.c.d.e.f.g.h
应该abcdefgh
a .b
应该提供a .b
,因为此处的.
与其左侧的空白相邻,因此无法替换a..::.:::.:bcde.. ...:fg
出于同样的原因应该abcde.. ...:fg
嗯,这是我尝试的(没有任何成功)。
尝试1:
s1 = r'a.b.c.d.e.f.g.h'
re.sub(re.search(r'[^\s.:]+([.:]+)[^\s.:]+', s1).group(1), r'', s1)
我希望获得'abcdefgh'
,但实际得到的是r''
。我理解为什么:代码
re.search(r'[^\s.:]+([.:]+)[^\s.:]+', s1).group(1)
返回'.'
而不是'\.'
,因此re.search
无法理解它必须替换单个句号.
而不是'.'
像通常的正则表达式。
尝试2:
s1 = r'a.b.c.d.e.f.g.h'
re.sub(r'([^\s.:]*\S)[.:]+(\S[^\s.:]*)', r'\g<1>\g<2>', s1)
这不起作用,因为它返回a.b.c.d.e.f.gh
。
尝试3:
s1 = r'a.b.c.d.e.f.g.h'
re.sub(r'([^\s.:]*)[.:]+([^\s.:]*)', r'\g<1>\g<2>', s1)
这适用于s1
,但它无法解决我的问题,因为在s2 = r'a .b'
它会返回a b
而不是a .b
。
有什么建议吗?
答案 0 :(得分:1)
这里有很多问题。你的正则表达式与你想匹配的东西不匹配;此外,您对re.sub
和re.search
的理解已经结束。
要找到某些内容,re.search
可让您找到字符串中发生某些事情的位置。
要替换某些内容,请在同一正则表达式而不是 re.sub
上使用re.search
,而不是。
并且,了解re.sub(r'thing(moo)other', '', s1)
用替换字符串替换整个匹配。
有了这个,你的正则表达式,听起来像你想要的
r'(?<![\s.:])[.:]+(?![\s.:])' # updated from comments, thanks!
包含一个带有句号和冒号的字符类(请注意方括号内不需要反斜杠 - 这是一个上下文,其中点和冒号没有任何特殊含义 1 ),尽可能多次重复;双方都认为,当两边都有空格\s
时,我们无法匹配这些字符,也不包括字符本身,因此正则表达式引擎无法通过应用{{找到匹配项1}}不那么严格(如果有办法的话,最好找到匹配)。
现在,正则表达式只匹配您想要实际替换的部分,因此您可以执行
+
虽然在更广泛的方案中,你还需要知道如何保留比赛的某些部分。为了演示的目的,我将使用一个正则表达式,它将点或冒号前后的文本捕获到带括号的组中:
>>> import re
>>> s1 = 'name.surname@domain.com'
>>> re.sub(r'(?<![\s.:])[.:]+(?![\s.:])', r'', s1)
'namesurname@domaincom'
查看替换字符串中的>>> re.sub(r'(.*\S)[.:]+(\S.*)', r'\g<1>\g<2>', s1)
'name.surname@domaincom'
如何引用&#34;无论第一组括号匹配&#34;并且类似\g<1>
到第二个带括号的组。
您还会注意到,这无法替换第一个句点,因为第一组括号内的\g<2>
匹配尽可能多的字符串。要避免这种情况,您需要一个只能尽可能少匹配的正则表达式。我们已经通过外观解决了上述问题,所以我会把你留在这里,尽管以不同的方式解决这个问题会很有趣(但并不太难)。
1 您甚至可以说正常的正则表达式语言(或语法,符号或形式)与方括号内的语言(或语法,符号或形式)分开! / p>