我想从主文本中分隔标点符号和符号,以便将它们拆分为单独的标记。我有一个包含以下符号%&()+,-./:;=–‘’“”″
的文本文件,我想用\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 &&
经过几次尝试,我意识到我无法编译正确的正则表达式。非常感谢您的帮助!
答案 0 :(得分:1)
处理您尝试执行的操作的正确方法是使用捕获组。这将让您参考您的比赛。首先,让我首先解释为什么你的尝试给你看到的输出。
在re.sub
函数中,当您将' '+str(pattern)+' '
作为第三个参数时,会将其计算为字符串" <_sre.SRE_Pattern object at some_memory_location> "
,因为str(pattern)
返回字符串表示形式模式对象,而不是模式。
顺便说一句,在Python 3.4和3.5上,str(pattern)
为我返回re.compile('[%&\\(\\)\\+,-./:;=–‘’“”″]')
,你使用的是什么版本的Python?它可能是Python 2的一个版本吗?
正如我之前提到的,您的解决方案需要使用捕获groups。要表示一个组,只需使用括号即可。在您的情况下,解决方案很简单,因为您只需要一个组:
>>> 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
之类的内容。这又是一个逃脱序列!
您的规范中不清楚您希望如何处理超过2个字符,例如三个字。因此,您的模式将如此处理这种情况:
>>> text2 = "hi. hi.. hi; hi;; 55% good& good&& hi &&& hello,"
>>> pattern.sub(r' \1 ', text2)
'hi . hi .. hi ; hi ;; 55 % good & good && hi &&& hello , '
也许这就是你的意思,但也许你想要考虑'&amp;&amp;&amp;&amp;'两个截然不同的比赛:'&amp;&amp;'和'&amp;'。您可以使用量词来处理这种情况:
>>> 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,}将匹配3或更多。