Python 使用正则表达式上下文替换字符串中的点
我想删除所有出现的由单个字符分隔的点,我还想用空格替换所有出现的由多个连续字符分隔的点(如果一侧有len>1个字符) 比如说。给定一个字符串Python 使用正则表达式上下文替换字符串中的点,python,regex,Python,Regex,我想删除所有出现的由单个字符分隔的点,我还想用空格替换所有出现的由多个连续字符分隔的点(如果一侧有len>1个字符) 比如说。给定一个字符串 s='A.B.C.D.E。FGH.IJ K.L.M.NO PQ.R.S T.U.VWXYZ' 处理后,输出应如下所示: 'ABCDE FGH IJ荷航无PQ RS TU VWXYZ' 请注意,在A.B.C.D.E.的情况下,所有点都会被删除(当没有尾随点时也应如此) 请注意,在K.L.M.NO的情况下,前两个点被删除,最后一个点被替换为空格(因为NO不是
s='A.B.C.D.E。FGH.IJ K.L.M.NO PQ.R.S T.U.VWXYZ'
处理后,输出应如下所示:
'ABCDE FGH IJ荷航无PQ RS TU VWXYZ'
- 请注意,在
的情况下,所有点都会被删除(当没有尾随点时也应如此)A.B.C.D.E.
- 请注意,在
的情况下,前两个点被删除,最后一个点被替换为空格(因为NO不是单个字符)K.L.M.NO
- 注意,在PQ.R.S
的情况下,第一个点被替换为空格,第二个点被删除
re.sub(r'(?不重要)对于用一个正则表达式来解决这个问题,或者甚至用正则表达式来解决这个问题
编辑:将示例字符串中的PQ.RS
更改为PQ.R.S
。您可以先用空格替换所有点,然后删除剩余点:
re.sub(r'\.([A-Z]{2})', r' \1', s).replace(".", "")
这为您的示例提供了“ABCDE FGH IJ KLM NO PQ RS TU VWXYZ”
。我将采取两个步骤
r'\1'
r'\1\2'
re1 = re.compile(r'(\b[A-Z])\.(?=[A-Z]\b|\s|$)')
re2 = re.compile(r'(\b[A-Z]{2,})\.(?=[A-Z])|(\b[A-Z])\.(?=[A-Z]{2,})')
s = ' A.B.C.D.E. FGH.IJ K.L.M.NO PQ.RS T.U.VWXYZ'
r = re2.sub(r'\1\2 ', re1.sub(r'\1', s)).strip()
print(r)
输出
'ABCDE FGH IJ KLM NO PQ RS TU VWXYZ'
符合您期望的结果:
'ABCDE FGH IJ KLM NO PQ RS TU VWXYZ'
匹配前面有独立字母,后面有另一个独立字母、空格或字符串结尾的所有点re1
匹配前面至少有2个字母,后面至少有1个字母的所有点(或相反)re2
- 希望这稍微整洁一点:
import re
s = ' A.B.C.D.E. FGH.IJ K.L.M.NO PQ.RS T.U.VWXYZ'
s = re.sub(r"\.(\w{2})", r" \1", s)
s = re.sub(r"(\w{2})\.(\w)", r"\1 \2", s)
s = re.sub(r"\.", "",s)
s = s.strip()
print(s)
如果您考虑使用动态替换:可以使用单个ReGEX解决方案:
重新导入
rx=r'\b([A-Z](?:\[A-Z])+\b(?:\.(?![A-Z])))|\.'
s='A.B.C.D.E.FGH.IJ K.L.M.无PQ.R.s T.U.VWXYZ'
打印(re.sub(rx,λx:x.group(1)。如果x.group(1)其他“”,则替换('.',''),s.strip())
#=>ABCDE FGH IJ荷航无PQ RS TU VWXYZ
请参阅和
正则表达式匹配:
-一个单词边界,然后是组1(在去掉所有句点后将被自身替换)捕获:\b([A-Z](?:\[A-Z])+\b(?:\.(?![A-Z]))
-大写ASCII字母[A-Z]
-零个或多个点和大写ASCII字母序列(?:\.[A-Z])+
-单词边界\b
-可选的(?:\.(?![A-Z])?
序列,后面不跟大写ASCII字母
-或|
-任何其他上下文中的\.
(将替换为空格)
lambda x:x.group(1)。如果x.group(1),则替换('.','')否则“”
replacement意味着,如果组1匹配,则替换字符串为组1值,不带点,如果组1不匹配,则替换为单个规则空格。您同意非正则表达式解决方案吗?是的,它不必是正则表达式。非常感谢!尽管我相信在这种情况下这会中断s='PQ.R.s
,它将给出PQRS
,而不是预期的PQRS
,我不确定您的规则是什么,但是您可以使用re.sub(r'([a-Z]{2}),r'\1',s)进行第二次传递(在删除点之前)
,它用空格替换前面两个字符的点。非常感谢!虽然我相信这会破坏案例s='PQ.R.s
,它将给出PQRS
,而不是预期的PQ RS
。我更新了示例以包含此案例。只是注意到您对另一个答案的答复。从您的回答中看不明显estion.Updated完美无瑕。非常感谢