python正则替换空格_Python|⽂本处理:⽤正则表达式替换
掉汉字(⾮英⽂)中间的空格...
⽹络上的⼀些⽂本,部分会有⼀些不必要的空格,如果想把空格全部替换掉,使⽤字符串string类的replace()⽅法即可,如:
str = place(' ','')
但如果是中英⽂混排的⽂本,如果想替换掉汉字中间的空格,⽽保留英⽂单词之间的空格,则问题的解决要复杂⼀些。需要⽤到正则表达式。
如有以下⽂档:
⾏(或段)的⾸尾、⼀些汉字之间有不必要的空格,需要替换掉。
⽤以下Python代码即可:
处理后的⽂本保存到了⽂档:
当然,⼀些有规律的乱码也可以处理。
上⾯有提到全部是中⽂的简单处理⽅法,也可以⽤⼀个简单的正则表达式判断⽂档或字符串内容是否包含“英⽂+空格+英⽂”的形式,然后⽤⼀个条件判断分别处理:
下⾯需要重点剖析⼀下上⾯关于正则表达式的概念及相关的⼀些内容:
正则表达式是⼀种⽤来匹配字符串的强有⼒的武器。它的设计思想是⽤⼀种描述性的语⾔来给字符串定义⼀个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。
1 compile()⽅法
向repile()传⼊⼀个字符串值,表⽰编译⼀个正则表达式,它将返回⼀个Regex 模式对象(或者就简称为Regex 对象)。
我们在Python中使⽤正则表达式时,re模块内部会做两件事情:I 编译正则表达式,如果正则表达式的字符串本⾝不合法,会报错;
II ⽤编译后的正则表达式去匹配字符串;
如果⼀个正则表达式要重复使⽤多次或⼀些较复杂的正则表达式,出于效率的考虑,我们可以预编译该正则表达式,接下来重复使⽤时就不需要编译这个步骤了,直接匹配。编译后⽣成Regular Expression对象。
可以向repile()传⼊re.IGNORECASE 或re.I,作为第⼆个参数,让正则表达式不区分⼤⼩写:>>> robocop =
repile(r'robocop', re.I)
>>> robocop.search('RoboCop is part man, part machine, all cop.').group()
'RoboCop'
2 r'……'的写法
r'……'表⽰忽略……可中可能存在的转义字符,当做普通字符看待;
3 中括号[]
有时候你想匹配⼀组字符,但缩写的字符分类(\d、\w、\s 等)太宽泛。你可以⽤⽅括号[]定义⾃⼰的字符分类。\d、\w 和\s 分别匹配数字、字母和空格。
\D、\W 和\S 分别匹配出数字、字母和空格外的所有字符。
例如,字符分类[aeiouAEIOU]将匹配所有元⾳字符(⼀个任意的元⾳字母),不论⼤⼩写。
Regex = repile(r'[aeiouAEIOU]')
也可以使⽤短横表⽰字母或数字的范围。例如,字符分类[a-zA-Z0-9]将匹配所有⼩写字母、⼤写字母和数字。
请注意,在⽅括号内,普通的正则表达式符号不会被解释。这意味着,你不需要前⾯加上倒斜杠转义.、*、?或()字符。例如,字符分类将匹配数字0 到5 和⼀个句点。你不需要将它写成[0-5\.],写成[0-5.]即可。
通过在字符分类的左⽅括号后加上⼀个插⼊字符(^),就可以得到“⾮字符类”。⾮字符类将匹配不在这个字符类中的所有字符。例如:
Regex = repile(r'[^aeiouAEIOU]')
[abc]匹配⽅括号内的任意字符(诸如a、b 或c)。
[^abc]匹配不在⽅括号内的任意字符。插⼊字符(^)还有另外⼀种⽤法,如果⽤在正则表达式的最前⾯,表明匹配必须发⽣在被查⽂本开始处。类似地,可以再正则表达式的末尾加上美元符号($),表⽰该字符串必须以这个正则表达式的模式结束。如正则表达式r'\d$'匹配以数字0 到9 结束的字符串。可以同时使⽤^和$,表明整个字符串必须匹配该模式。
^spam 意味着字符串必须以spam 开始。
spam$意味着字符串必须以spam 结束。
4 \s 和\S
\s 空格、制表符或换⾏符(可以认为是匹配“空⽩”字符);
\S 除空格、制表符和换⾏符以外的任何字符;
5 问号?、星号*、加号+、半⾓句号.
匹配零次或⼀次前⾯的分组。
* 匹配零次或多次前⾯的分组。
+ 匹配⼀次或多次前⾯的分组。
. 匹配所有字符,换⾏符\n除外。
问号?在正则表达式中可能有两种含义:声明⾮贪⼼匹配或表⽰可选的分组。这两种含义是完全⽆关的。
在字符串'HaHaHaHaHa'中,因为(Ha){3,5}可以匹配3 个、4 个或5 个实例,你可能会想,为什么在前⾯花括号的例⼦中,Match 对象的group()调⽤会返
回'HaHaHaHaHa',⽽不是更短的可能结果。毕竟,'HaHaHa'和'HaHaHaHa'也能够有效地匹配正则表达式(Ha){3,5}。
Python 的正则表达式默认是“贪⼼”的,这表⽰在有⼆义的情况下,它们会尽可能匹配最长的字符串。花括号的“⾮贪⼼”版本匹配尽可能最短的字符串,即在结束的花括号后跟着⼀个问号。
{n,m}?或*?或+?对前⾯的分组进⾏⾮贪⼼匹配。
⼤括号{}
表⽰匹配{}前⾯分组的次数。
{n}匹配n 次前⾯的分组。
{n,}匹配n 次或更多前⾯的分组。
{,m}匹配零次到m 次前⾯的分组。
{n,m}匹配⾄少n 次、⾄多m 次前⾯的分组。
{n,m}?或*?或+?对前⾯的分组进⾏⾮贪⼼匹配。
6 \u4e00-\u9fa5
表⽰汉字unicode编码⽅式下的编码范围,多达20892⽅块字(5*16*16*16=20480)。
后⾯部分:
最后⼀个⽅块字是龥,yù,呼也。UniCode CJK编码:U+9FA5,五笔:WGKMpython正则表达式不包含
7 ⼩括号()
有时候,你可能需要使⽤匹配的⽂本本⾝,作为替换的⼀部分。替换时使⽤\1、\2、\3……。表⽰“在替换中输⼊分组1、2、3……的⽂本”。(可以理解为需要保留部分)
除了简单地判断是否匹配之外,正则表达式还有提取⼦串的强⼤功能。match⽅法配合⽤()表⽰的就是要提取的分组(Group)。
⽐如 ^(\d{3})-(\d{3,8})$分别定义了两个组,可以直接从匹配的字符串中提取出区号和本地号码:>>>
m = re.match(r'^(\d{3})-
(\d{3,8})$', '010-12345')
>>> m.group(0)
'010-12345'
>>> m.group(1)
'010'
>>> m.group(2)
'12345'
如果正则表达式中定义了组,就可以在Match对象上⽤group()⽅法提取出⼦串来。
注意到group(0)永远是原始字符串,group(1)、group(2)……表⽰第1、2、……个⼦串。
8 Regex对象的sub()⽅法
正则表达式不仅能到⽂本模式,⽽且能够⽤新的⽂本替换掉这些模式。Regex对象的sub()⽅法需要传⼊两个参数。第⼀个参数是⼀个字符串,⽤于取代发现的匹配。第⼆个参数是⼀个字符串,即正则表达式。
sub()⽅法返回替换完成后的字符串。如:resup =repile(r'(\[\d*\])') # 上标处理
s = resup.sub(r'\1', s)
9 re的findall()⽅法
findall()⽅法将返回⼀组字符串,包含被查字符串中的所有匹配。(search()将返回⼀个Match对象,包含被查字符串中的“第⼀次”匹配的⽂本。)
利⽤findall()⽅法,可以到“所有”匹配的地⽅。另⼀⽅⾯,findall()不是返回⼀个Match 对象,⽽是返回⼀个字符串列表。以下两种写法都可以:list1 = re.findall(pattern,strs)
list1 = pattern.findall(strs)
10 split()⽅法
split()⽅法提供强⼤了字符串切割功能,可以按正则表达式指定的字符进⾏切割,返回⼀个列表。
如⽤空格切割:>>> 'a b c'.split(' ')
['a', 'b', '', '', 'c']
⽤多个空格切割:>>> re.split(r'\s+', 'a b c')
['a', 'b', 'c']
⽤多个字符进⾏切割:re.split(r'[\s\,\;]+', 'a,b;; c d')
['a', 'b', 'c', 'd']
关于中⽂字符匹配,为了加深理解,可以再看⼀下下⾯的例⼦:
常⽤正则表达式,可以总结⼀下:?匹配零次或⼀次前⾯的分组。
*匹配零次或多次前⾯的分组。
+匹配⼀次或多次前⾯的分组。
{n}匹配n 次前⾯的分组。
{n,}匹配n 次或更多前⾯的分组。
{,m}匹配零次到m 次前⾯的分组。
{n,m}匹配⾄少n 次、⾄多m 次前⾯的分组。
{n,m}?或*?或+?对前⾯的分组进⾏⾮贪⼼匹配。
^spam 意味着字符串必须以spam 开始。
spam$意味着字符串必须以spam 结束。
.匹配所有字符,换⾏符除外。
\d、\w 和\s 分别匹配数字、单词和空格。
\D、\W 和\S 分别匹配出数字、单词和空格外的所有字符。
[abc]匹配⽅括号内的任意字符(诸如a、b 或c)。
[^abc]匹配不在⽅括号内的任意字符。
字符|称为“管道”。希望匹配许多表达式中的⼀个时,就可以使⽤它。例如,正则表达式r'Batman|Tina Fey'将匹配'Batman'或'Tina
Fey'。
正则表达式以外的其它补充:
字符串的strip()⽅法:可以删除掉字符串⾸尾两端的空格,包括\n,还可以删除掉⾸尾两端的指定字符,形式如strip([str])。strip()⽅⾯的功能可以分解为lstrip()和rstrip()。
附代码:import re
f0 = open('','w',encoding='UTF-8')
#处理⽂本中的空格,只要含有“英⽂+空格+英⽂”就不处理
pattern =repile(u'[a-zA-Z]+\s+[a-zA-Z]+')
with open('', 'rU') as file:
....strs = ad()
....entxt = re.findall(pattern,strs)
if (not entxt):
'''
....s = s.replace('.' , '。')
....s = s.replace(',' , ',')
....s = s.replace('!' , '!')
....s = s.replace('?' , '?')
....'''
....s = place(' ','') # 处理全⾓空格
....s = s.replace(' ' , '') # 处理半⾓空格(全中⽂可以使⽤)
....f0.write(s)
.
...f0.close()
else:
....pattern =repile(r'([\u4e00-\u9fa5,]{1})\s+([\u4e00-\u9fa5,]{1})') ....with open('', 'rU') as f2:
........str = f2.readline()
........while str: # readline()⽅法读到最后会返回⼀个空字符............s = place(' ','') # 处理全⾓空格
............s = pattern.sub(r'\1\2', str)
............s = s.strip() + '\n' # strip()⽅法会把尾端的\n也去掉............f0.write(s)
............str = f2.readline() # readline()⽅法每次只读取⼀⾏
....f0.close() # 如果不是使⽤上⾯的with⽅法,需要close()后⽂档才会写⼊ -End-
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论