第11.23节 Python 中re模块的搜索替换功能:sub及subn函数

一、 引言
在《第11.3节 Python正则表达式搜索支持函数search、match、fullmatch、findall、finditer》重点介绍了几个搜索函数,除了搜索,re模块也提供搜索并替换功能,这个就是re模块的sub函数。

二、 语法释义

  1. 调用语法:
    re.sub(pattern, repl, string, count=0, flags=0)
    re.subn(pattern, repl, string, count=0, flags=0)

  2. 参数:
    1)pattern:匹配的正则表达式;
    2)string:搜索文本字符串
    3)repl:替换对象,将搜索文本中和模式匹配的字符串替换为repl对象对应的内容,repl可以是,或者是字符串一个函数
    4)count:用于限制最多替换多少次,为0或者没有传入则全部替换;
    5)flags:搜索标记,与《第11.2节 Python 正则表达式支持函数概览》介绍的参数flags标记含义相同。

  3. 返回值:
    sub返回通过使用 repl 替换在通过正则表达式模式搜索到的字符串。 如果没有找到匹配子串,则直接返回 string。
    subn与sub函数一样执行搜索替换,但是不是返回替换后的字符串,而是返回一个元组,元组的第一个元素是替换后的字符串(该元素与sub返回值相同),第二个元素是执行替换的次数。

三、 关于repl参数的说明

  1. 可以是字符串,如为字符串,则其中任何反斜杠转义序列都会被按转义结果处理, 也就是说,\n 会被转换为一个换行符,\r 会被转换为一个回车附,…。 未知的 ASCII 字符转义序列会被当作错误来处理,其他未知转义序列例如 \&会保持原样;
  2. repl如果是字符串,可以使用组名如\g或组序号如 \1、\g<序号>的后向引用,实际处理时会使用组匹配结果的对应组所匹配到的子字符串来执行目标串的替换;
  3. 如果repl是函数类型:
    1)函数只能带一个参数,参数类型必须是匹配对象;
    2)该匹配对象是Python每匹配到一个搜索串时调用,由于搜索内容是由整个正则表达式确认的,因此一般情况下搜索串应该是以代表整个搜索内容的组0对应结果作为处理数据进行处理,除非有特殊处理要求再考虑使用其他组;
    3)Python在每匹配到一个该函数对匹配对象处理的结果进行处理后的返回内容作为替换字符串。

四、 案例

  1. 分别调用sub和subn使用字符串作为替换内容,字符串包含组名和组序号
>>> re.sub(r'(?i)(?P<lab>py\w*)',r'\1:\g<1>:\g<lab>->Python','Python?PYTHON!Learning python with LaoYuan! ')
'Python:Python:Python->Python?PYTHON:PYTHON:PYTHON->Python!Learning python:python:python->Python with LaoYuan! '

>>>re.subn(r'(?i)(?P<lab>py\w*)',r'\1:\g<1>:\g<lab>->Python','Python?PYTHON!Learning python with LaoYuan! ')
('Python:Python:Python->Python?PYTHON:PYTHON:PYTHON->Python!Learning python:python:python->Python with LaoYuan! ', 3)
>>>

上述案例中,\1:\g<1>:\g<lab>都是访问的匹配的字符串,除了不论大小写的“python”,其他诸如“py”、“pyth”等py开头的字符串都会被替换为“Python”。

  1. 使用函数作为替换内容
    本案例将小说的中文章节中的数字替换为阿拉伯数字,定义了函数transnumber将中文数字翻译成阿拉伯数字,在正则表达式中找章节并调用函数transnumber执行替换。
>>> def transnumber(m):
    numbdict={'零':'0','一':'1','二':'2','三':'3','四':'4','五':'5','六':'6','七':'7','八':'8','九':'9','十':'','百':''}
    result=[]
    for i in m.group(0):result.append(numbdict[i])
    resultstr = ''.join(result)
    print("group(0):",m.group(0),"groups:",m.groups(),"result:",resultstr)
    return resultstr

>>> re.sub(r'(?<=第)([一-十零百]+)(?=[章,回])',transnumber,'第一回第二回第九十七回第一百零八回第七百二十二回')
group(0): 一 groups: ('一',) result: 1
group(0): 二 groups: ('二',) result: 2
group(0): 九十七 groups: ('九十七',) result: 97
group(0): 一百零八 groups: ('一百零八',) result: 108
group(0): 七百二十二 groups: ('七百二十二',) result: 722
'第1回第2回第97回第108回第722回'

>>> re.subn(r'(?<=第)([一-十零百]+)(?=[章,回])',transnumber,'第一回第二回第九十七回第一百零八回第七百二十二回')
group(0): 一 groups: ('一',) result: 1
group(0): 二 groups: ('二',) result: 2
group(0): 九十七 groups: ('九十七',) result: 97
group(0): 一百零八 groups: ('一百零八',) result: 108
group(0): 七百二十二 groups: ('七百二十二',) result: 722
('第1回第2回第97回第108回第722回', 5)
>>>

老猿Python,跟老猿学Python!
博客地址:https://blog.csdn.net/LaoYuanPython

请大家多多支持,点赞、评论和加关注!谢谢!

posted on 2019-08-23 20:14  老猿Python  阅读(321)  评论(0编辑  收藏  举报