我想将标点符号和符号从主文本中分离出来,以便将它们分割成单独的标记。我有一个包含以下符号%&()+,-./:;=–‘’“”″的文本文件,我想用\ssymbol\s替换每个符号( \s表示一个空格),如果两个相同类型的符号(例如,.. )相邻,我想用\s..\s替换它们。这就是我迄今尝试过的:
>>> punc = "[%&\(\)\+,-./:;=–‘’“”″]+"
>>> import re
>>> pattern = re.compile(punc)
>>> text = "hi. hi.. hi; hi;; 55% good& good&&"
>>> text = re.sub(pattern, ' '+str(pattern)+' ', text)当我打印文本时,我得到以下内容:
>>> print(text)
hi <_sre.SRE_Pattern object at 0x00000000035E14E0> hi <_sre.SRE_Pattern object at 0x00000000035E14E0> hi <_sre.SRE_Pattern object at 0x00000000035E14E0> hi <_sre.SRE_Pattern object at 0x00000000035E14E0> 55 <_sre.SRE_Pattern object at 0x00000000035E14E0> x <_sre.SRE_Pattern object at 0x00000000035E14E0> 但我希望输出是这样的:
hi . hi .. hi ; hi ;; 55 % good & good &&经过几次尝试,我意识到我无法编译正确的regex。我们非常感谢您的帮助!
发布于 2016-07-20 06:43:23
处理您想要做的事情的正确方法是使用捕获组。这将让你回到你的对手。首先,让我先解释一下为什么您的尝试会给出您所看到的输出。
为什么你看到了你看到的
在re.sub函数中,当您将' '+str(pattern)+' '作为第三个参数时,它将被计算为string " <_sre.SRE_Pattern object at some_memory_location> ",因为str(pattern)返回模式对象的字符串表示,而不是模式的字符串表示。
顺便说一句,在Python3.4和3.5上,str(pattern)会为我返回re.compile('[%&\\(\\)\\+,-./:;=–‘’“”″]'),您使用的是哪个版本的Python?它可能是Python 2的一个版本吗?
解决方案
正如我前面提到的,您的解决方案需要使用捕获群组。要表示一个组,只需使用括号。在您的例子中,解决方案非常简单,因为您只需要一个组:
>>> import re
>>> pattern = re.compile(r"([%&\(\)\+,-./:;=–‘’“”″]+)")注意,对于字符串文本,我在字符串开始之前使用了r。这表示原始字符串,这将导致字符串忽略Python定义的任何转义序列。例如,转义序列类似于'\t',它表示一个选项卡。但是,如果您使用r'\t',那么它就是实际的字符串\t。
>>> text = "hi. hi.. hi; hi;; 55% good& good&&"
>>> pattern.sub(r' \1 ', text)
'hi . hi .. hi ; hi ;; 55 % good & good && '注意,我只是使用了模式对象的sub方法,而不是模块级函数re.sub。这没什么大不了的,但对我来说就更干净了。另外,对于替换参数,我使用了r' \1 '。这个\1指的是您的模式捕获的第一个组。例如,如果您有多个组,您可以使用类似于\2 \1的东西来反转某些模式。再说一遍,这是一个逃逸序列!
潜在的改进
在您的规范中,不清楚您想如何处理两个以上的字符,例如三个字符。所以你的模式会很好地处理这种情况:
>>> text2 = "hi. hi.. hi; hi;; 55% good& good&& hi &&& hello,"
>>> pattern.sub(r' \1 ', text2)
'hi . hi .. hi ; hi ;; 55 % good & good && hi &&& hello , '也许这就是你要做的,但也许你想把“&”看作是两个截然不同的匹配:“&&”和“&”。您可以使用量词来处理这种情况:
>>> pattern2 = re.compile(r'([%&\(\)\+,-./:;=–‘’“”″]{1,2})')
>>> pattern2.sub(r' \1 ', text2)
'hi . hi .. hi ; hi ;; 55 % good & good && hi && & hello , '与使用表示一个或多个的+符号不同,您可以使用括号符号来具有更细粒度的控件。例如,{1, 3 }将匹配1到3。{3}将完全匹配。{3,}将匹配3或更多。
https://stackoverflow.com/questions/38470073
复制相似问题