首页 > 程序开发 > Web开发 > Python >

Python——正则表达式(4)

2016-03-02

本文译自官方文档: Regular Expression HOWTO 参考文章: Python——正则表达式(1) Python——正则表达式(2) Python——正则表达式(3) 全文下载: Python正则表达式基础 ===============================

5.修改字符串

到目前为止,我们只是知道了如何在静态的字符串上执行搜索。正则表达式也可以通过使用下述模式方法修改字符串:

方法/属性 功能
split() 在正则表达式匹配的地方进行分割,返回一个列表
sub() 找到所有匹配的子字符串,并替换为新的子串
subn() 和sub()方法做同样的事情,但返回新的字符串以及替换的数目
---------------------------------------------------------------------------------------------------------------------------------------------------

5.1.分割字符串
模式对象的split()方法在正则表达式匹配的地方进行分割,并将分割的结果作为列表返回。它和Python字符串的split()方法有些类似, Python字符串的split()方法支持按照空格或者按照固定的字符串分割,但是它提供更广泛的分隔符。正如你所预想的,它同时也提供一个模块级别的函数re.split()。

split(string [, maxsplit = 0])
按照正则表达式匹配来分割字符串。如果在正则表达式中使用了捕获组,那么它们的内容也将作为一个列表的一部分返回。如果maxsplit不为0,表示至多有maxsplit个分割会被处理。

你可以通过传入maxsplit参数来确定分割的数量,当maxsplit不为0时,最多有maxsplit个分割会被处理,剩下的字符串将会作为列表的最后一项返回。在下述例子中,分隔符是任意的非字母数字字符序列。

>>> p = re.compile(r'\W+')
>>> p.split('This is a test,short and sweet,of split().')
['This', 'is', 'a', 'test', 'short', 'and', 'sweet', 'of', 'split', '']
>>> p.split('This is a test,short and sweet,of split().',3)
['This', 'is', 'a', 'test,short and sweet,of split().']
有时候你不仅对分隔符之间的内容感兴趣,还对分隔符本身感兴趣。如果在正则表达式中使用捕获分组,那么它们的内容将作为列表的一部分返回,

对比下述例子:

>>> p = re.compile(r'\W+')
>>> p2 = re.compile(r'(\W+)')
>>> p.split('This... is a test.')
['This', 'is', 'a', 'test', '']
>>> p2.split('This... is a test.')
['This', '... ', 'is', ' ', 'a', ' ', 'test', '.', '']
模块级别的函数re.split()除了将正则表达式作为第一参数外,其他是一样的。
>>> re.split(r'[\W]+','Words,words,words.')
['Words', 'words', 'words', '']
>>> re.split(r'([\W]+)','Words,words,words.')
['Words', ',', 'words', ',', 'words', '.', '']
>>> re.split(r'[\W]+','Words,words,words.',1)
['Words', 'words,words.']
---------------------------------------------------------------------------------------------------------------------------------------------------
5.2.查找和替换
另一个常见的任务就是找到匹配的所有子字符串,并且将它们替换成新的子串。sub方法有一个replacement参数,可以接受一个字符串或者一个处理字符串的函数。

sub(replacement , string [ , count=0])
返回一个字符串,这个字符串从左边开始,所有RE匹配的地方都替换成replacement。如果没有找到任何匹配的内容,那么返回原来的字符串。
可选参数count是指定模式替换的最大次数。count必须是一个非负数,默认值0表示替换所有匹配的地方。

下述是一个使用sub()方法的简单例子,它用单词colour替换所有颜色的名字。
>>> p = re.compile('(blue|white|red)')
>>> p.sub('colour','blue socks and red shoes')
'colour socks and colour shoes'
>>> p.sub('colour','blue socks and red shoes',1)
'colour socks and red shoes'
subn()方法与sub()功能一致,但是subn()方法会返回一个包含两个元素的元组:新的字符串和执行替换的次数:
>>> p = re.compile('blue|white|red')
>>> p.subn('colour','blue socks and red shoes')
('colour socks and colour shoes', 2)
>>> p.subn('colour','no colours at all')
('no colours at all', 0)
空匹配只有在它们没有紧挨着前面的匹配时才会被替换掉:
>>> p = re.compile('x*')
>>> p.sub('-','abxd')
'-a-b-d-'
如果 replacement 参数是一个字符串,那么之中的反斜杠都会被处理。比如 \n 将会被转换成一个换行符,\r会被 转换成回车,等等。未知的转义如 \j 保持原样。逆向引用,如 \6,则被 RE 中相应的捕获组匹配的内容所替换。这使你可以在替换后的字符串中插入一部分原字符串。

下述这个例子将匹配后面跟着大括号{ }的单词section,并将section替换成subsection:
>>> p = re.compile('section{([^}]*)}',re.VERBOSE)
>>> p.sub(r'subsection{\1}','section{First} section{Second}')
'subsection{First} subsection{Second}'
还可以使用Python的扩展语法 (?P) 指定命名组,\g 将会替换成名称为name的分组匹配的内容,并且,\g<数字> 也可以使用分组序号引用。\g<2>和 \2 的作用是一样的,但是它更清晰,比如在这样的表达式中:\g<2>0,它表示引用分组序号为2的分组内容,后面再匹配数字0,而如果换成第一种写法就会变成:\20,这样会让匹配引擎认为是引用第20个分组的内容。下述三个例子是一样的替换,但是用了三个不同的replacement字符串:
>>> p = re.compile(&#39;section{ (?P[^}]*) }&#39;,re.VERBOSE)
>>> p.sub(r&#39;subsection{\1}&#39;,&#39;section{First}&#39;)
&#39;subsection{First}&#39;
>>> p.sub(r&#39;subsection{\g<1>}&#39;,&#39;section{First}&#39;)
&#39;subsection{First}&#39;
>>> p.sub(r&#39;subsection{\g}&#39;,&#39;section{First}&#39;)
&#39;subsection{First}&#39;
replacement参数也可以是一个函数,这可以让你实现更多的功能。如果replacement参数是一个函数,该函数将会在正则表达式模式每次不重复匹配的时候被调用。在每次调用时,函数会收到一个匹配对象的参数,因此你就可以利用这个对象去计算出新的字符串并返回它。

下述例子,replacement方法将十进制数字转换成十六进制:
>>> def hexrepl(match):
	&#39;&#39;&#39;Return the hex string for a decimal number&#39;&#39;&#39;
	value = int(match.group())
	return hex(value)

>>> p = re.compile(r&#39;\d+&#39;)
>>> p.sub(hexrepl,&#39;Call 65490 for printing, 49152 for user code.&#39;)
&#39;Call 0xffd2 for printing, 0xc000 for user code.&#39;
当使用模块级函数re.sub()的时候,正则表达式模式同样作为第一参数传递。该模式可以是一个字符串或一个编译好的对象。如果你需要指定正则表达式编译标志,那么你必须使用后者;或者使用模式内嵌修正器,例如,sub("(?i)b+", "x", "bbbb BBBB") 返回 &#39;x x&#39;。
相关文章
最新文章
热点推荐