首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用regexPython3.x用space+substring+space替换子字符串

用regexPython3.x用space+substring+space替换子字符串
EN

Stack Overflow用户
提问于 2016-07-19 23:23:07
回答 1查看 194关注 0票数 0

我想将标点符号和符号从主文本中分离出来,以便将它们分割成单独的标记。我有一个包含以下符号%&()+,-./:;=–‘’“”″的文本文件,我想用\ssymbol\s替换每个符号( \s表示一个空格),如果两个相同类型的符号(例如,.. )相邻,我想用\s..\s替换它们。这就是我迄今尝试过的:

代码语言:javascript
复制
>>> punc = "[%&\(\)\+,-./:;=–‘’“”″]+"
>>> import re
>>> pattern = re.compile(punc)
>>> text = "hi. hi.. hi; hi;; 55% good& good&&"
>>> text = re.sub(pattern, ' '+str(pattern)+' ', text)

当我打印文本时,我得到以下内容:

代码语言:javascript
复制
>>> 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> 

但我希望输出是这样的:

代码语言:javascript
复制
hi . hi .. hi ; hi ;; 55 % good & good &&

经过几次尝试,我意识到我无法编译正确的regex。我们非常感谢您的帮助!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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的一个版本吗?

解决方案

正如我前面提到的,您的解决方案需要使用捕获群组。要表示一个组,只需使用括号。在您的例子中,解决方案非常简单,因为您只需要一个组:

代码语言:javascript
复制
>>> import re
>>> pattern = re.compile(r"([%&\(\)\+,-./:;=–‘’“”″]+)")

注意,对于字符串文本,我在字符串开始之前使用了r。这表示原始字符串,这将导致字符串忽略Python定义的任何转义序列。例如,转义序列类似于'\t',它表示一个选项卡。但是,如果您使用r'\t',那么它就是实际的字符串\t

代码语言:javascript
复制
>>> 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的东西来反转某些模式。再说一遍,这是一个逃逸序列!

潜在的改进

在您的规范中,不清楚您想如何处理两个以上的字符,例如三个字符。所以你的模式会很好地处理这种情况:

代码语言:javascript
复制
>>> text2 = "hi. hi.. hi; hi;; 55% good& good&& hi &&& hello,"
>>> pattern.sub(r' \1 ', text2)
'hi .  hi ..  hi ;  hi ;;  55 %  good &  good &&  hi  &&&  hello , '

也许这就是你要做的,但也许你想把“&”看作是两个截然不同的匹配:“&&”和“&”。您可以使用量词来处理这种情况:

代码语言:javascript
复制
>>> 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或更多。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38470073

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档