您现在的位置是: 网站首页 >Python Python
Python3 re正则表达式
admin2018年10月7日 13:04 【Python 】 1056人已围观
# Python3 re正则表达式 ## 匹配规则 |模式|描述| |---|---| |\w|匹配字母数字及下划线。等价于[A-Za-z0-9_]。| |\W|匹配非字母数字及下划线。等价于[^A-Za-z0-9_]。| |\s|匹配任意空白字符,等价于 [\t\n\r\f].| |\S|匹配任意非空字符。等价于 [^ \f\n\r\t\v]| |\d|匹配任意数字,等价于 [0-9]| |\D|匹配任意非数字。等价于 [^0-9]。| |\A|匹配字符串开始| |\Z|匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串| |\z|匹配字符串结束| |\G|匹配最后匹配完成的位置| |\n|匹配一个换行符| |\t|匹配一个制表符| |^|匹配字符串的开头| |$|匹配字符串的末尾。| |.|匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。| |[.\n]|匹配包括 '\n' 在内的任何字符| |[...]|用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k'| |[^...]|不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。| |*|匹配0个或多个的表达式。| |+|匹配1个或多个的表达式。| |?|匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式| |{n}|精确匹配n个前面表达式。| |`{n, m}`|匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式| |`a|b`|匹配a或b| |( )|匹配括号内的表达式,也表示一个组| |[Pp]ython| 匹配 "Python" 或 "python"| |rub[ye]| 匹配 "ruby" 或 "rube"| |[aeiou]| 匹配中括号内的任意一个字母| |[0-9] |匹配任何数字。类似于 [0123456789]| |[a-z] |匹配任何小写字母| |[A-Z]| 匹配任何大写字母| |[a-zA-Z0-9]| 匹配任何字母及数字| |[^aeiou]| 除了aeiou字母以外的所有字符| |[^0-9] |匹配除了数字外的字符| ## 特殊字符需要转义 | 特别字符 | 说明 | |---|---| | `$` | 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 `$` 也匹配 `\n` 或 `\r`。要匹配 `$` 字符本身,请使用 `\$`。 | | `( ) `| 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 和和。 | | `*` | 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。 | | `+` | 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+。 | | `.` | 匹配除换行符 \n之外的任何单字符。要匹配 .,请使用 \。 | | `[ ]` | 标记一个中括号表达式的开始。要匹配 [,请使用 \[。 | | `?` | 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?。 | | `\` | 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, ‘n' 匹配字符‘n'。'\n' 匹配换行符。序列 ‘\\' 匹配 “\”,而 ‘\(' 则匹配 “(”。 | | `^` | 匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符本身,请使用 \^。 | | `{ }` | 标记限定符表达式的开始。要匹配 `{`,请使用 `\{`。 | | `|` | 指明两项之间的一个选择。要匹配 `|`,请使用` \|`。 | ## match() 向`re.match()`方法传入要匹配的字符串以及正则表达式,就可以来检测这个正则表达式是否匹配字符串了。 match()方法会尝试从字符串的起始位置匹配正则表达式,如果匹配,就返回匹配成功的结果,如果不匹配,那就返回None。 ```python import re content = 'Hello 123 4567 World_This is a Regex Demo' print(len(content)) # 41 result = re.match(r'^Hello\s\d\d\d\s\d{4}\s\w{10}', content) print(result) # <_sre.SRE_Match object; span=(0, 25), match='Hello 123 4567 World_This'> print(result.group()) # Hello 123 4567 World_This print(result.span()) # (0, 25) res = re.match(r'^Hello\s\d+\s\d+\s\w+', content) print(res) # <_sre.SRE_Match object; span=(0, 25), match='Hello 123 4567 World_This'> ``` 在这里首先声明了一个字符串,包含英文字母、空白字符、数字等等内容,接下来写了一个正则表达式`^Hello\s\d\d\d\s\d{4}\s\w{10}`来匹配这个长字符串。 * 开头的^是匹配字符串的开头,也就是以Hello开头, * 然后\s匹配空白字符,用来匹配目标字符串的空格, * \d匹配数字,三个\d匹配123, * 然后再写一个\s匹配空格, * 后面还有4567,其实可以依然用四个\d来匹配,但是这么写起来比较繁琐,所以在后面可以跟{4}代表匹配前面的字符四次,也就是匹配四个数字,这样也可以完成匹配, * 然后后面再紧接一个空白字符,然后\w{10}匹配10个字母及下划线,正则表达式到此为止就结束了,注意到其实并没有把目标字符串匹配完,不过这样依然可以进行匹配,只不过匹配结果短一点而已。 调用`match()`方法,**第一个参数传入了正则表达式,第二个参数传入了要匹配的字符串。** 打印输出一下结果,可以看到结果是SRE_Match对象,证明成功匹配,它有两个方法: * `group()`方法可以输出匹配到的内容,结果是`Hello 123 4567 World_This`,这恰好是正则表达式规则所匹配的内容, * `span()`方法可以输出匹配的范围,结果是`(0, 25)`,这个就是匹配到的结果字符串在原字符串中的位置范围。 通过上面的例子可以基本了解怎样在Python中怎样使用正则表达式来匹配一段文字。 ## 匹配目标 刚才用了`match()`方法可以得到匹配到的字符串内容,但是如果想从字符串中提取一部分内容怎么办呢?就像最前面的实例一样,从一段文本中提取出邮件或电话号等内容。 在这里可以使用`()`括号来将想提取的子字符串括起来,`()`实际上就是标记了一个子表达式的开始和结束位置,被标记的每个子表达式会依次对应每一个分组,可以调用`group()`方法传入分组的索引即可获取提取的结果。 ```python content = 'Hello 1234567 World_This is a Regex Demo' result = re.match(r'^Hello\s(\d+)\sWorld', content) print(result) # <_sre.SRE_Match object; span=(0, 19), match='Hello 1234567 World'> print(result.group()) # Hello 1234567 World print(result.group(0)) # Hello 1234567 World print(result.group(1)) # 1234567 print(result.span()) # (0, 19) ``` 依然是前面的字符串,在这里想匹配这个字符串并且把其中的`1234567`提取出来,在这里将数字部分的正则表达式用`()`括起来,然后接下来调用了group(1)获取匹配结果。 可以看到在结果中成功得到了`1234567`,获取用的是`group(1)`,与`group()`有所不同,`group()`会输出完整的匹配结果,而`group(1)`会输出第一个被`()`包围的匹配结果,假如正则表达式后面还有`()`包括的内容,那么可以依次用`group(2)`、`group(3)`等来依次获取。 ## 通用匹配 刚才写的正则表达式其实比较复杂,出现空白字符就写`\s`匹配空白字符,出现数字就写`\d`匹配数字,工作量非常大,其实完全没必要这么做,还有一个万能匹配可以用,也就是`.*`,`.`可以匹配任意字符(除换行符),`*`又代表匹配前面的字符无限次,所以它们组合在一起就可以匹配任意的字符了,有了它就不用挨个字符地匹配了。在这里将中间的部分直接省略,全部用.*来代替,最后加一个结尾字符串就好了。 ```python content = 'Hello 123 4567 World_This is a Regex Demo' result = re.match(r'^Hello.*Demo$', content) print(result) # <_sre.SRE_Match object; span=(0, 41), match='Hello 123 4567 World_This is a Regex Demo'> print(result.group()) # Hello 123 4567 World_This is a Regex Demo ``` 可以看到`group()`方法输出了匹配的全部字符串,也就是说写的正则表达式匹配到了目标字符串的全部内容,`span()`方法输出`(0, 41)`,是整个字符串的长度。 因此,可以在使用`.*`来简化正则表达式的书写。 ## 贪婪匹配与非贪婪匹配 在使用上面的通用匹配.*的时候可能有时候匹配到的并不是想要的结果: ```python content = 'Hello 1234567 World_This is a Regex Demo' result = re.match(r'^He.*(\d+).*Demo$', content) print(result) # <_sre.SRE_Match object; span=(0, 41), match='Hello 123 4567 World_This is a Regex Demo'> print(result.group(1)) # 7 ``` 在这里依然是想获取中间的数字,所以中间依然写的是`(\d+)`,数字两侧由于内容比较杂乱,所以两侧想省略来写,都写`.*`,最后组成`^He.*(\d+).*Demo$`,看样子并没有什么问题,但奇怪的事情发生了,只得到了7这个数字,这是怎么回事? 这里就涉及一个贪婪匹配与非贪婪匹配的原因了,贪婪匹配下,`.*`会匹配尽可能多的字符,正则表达式中`.*`后面是`\d+`,也就是至少一个数字,并没有指定具体多少个数字,所以`.*`就尽可能匹配多的字符,所以它把`123456`也匹配了,给`\d+`留下一个可满足条件的数字`7`,所以`\d+`得到的内容就只有数字`7`了。 但这样很明显会给匹配带来很大的不便,有时候匹配结果会莫名其妙少了一部分内容。其实这里只需要使用非贪婪匹配匹配就好了,非贪婪匹配的写法是`.*?`,多了一个`?`,那么它可以达到怎样的效果? ```python result = re.match(r'^He.*?(\d+).*Demo$', content) print(result) # <_sre.SRE_Match object; span=(0, 40), match='Hello 1234567 World_This is a Regex Demo'> print(result.group(1)) # 1234567 ``` 只是将第一个`.*`改成了`.*?`,转变为非贪婪匹配匹配 很好,这下就可以成功获取`1234567`了。原因可想而知,贪婪匹配是尽可能匹配多的字符,非贪婪匹配就是尽可能匹配少的字符,`.*?`之后是`\d+`用来匹配数字,当`.*?`匹配到`Hello`后面的空白字符的时候,再往后的字符就是数字了,而`\d+`恰好可以匹配,那么这里`.*?`就不再进行匹配,交给`\d+`去匹配后面的数字。所以这样,`.*?`匹配了尽可能少的字符,`\d+`的结果就是`1234567`了。 所以说,在做匹配的时候,字符串中间可以尽量使用非贪婪匹配来匹配,也就是用`.*?`来代替`.*`,以免出现匹配结果缺失的情况。 但这里注意,如果匹配的结果在字符串结尾,`.*?`就有可能匹配不到任何内容了,因为它会匹配尽可能少的字符,例如: ```python content = 'http://weibo.com/comment/kEraCN' result1 = re.match(r'http.*?comment/(.*?)', content) result2 = re.match(r'http.*?comment/(.*)', content) print(result1, result1.group(1)) print(result2, result2.group(1)) # <_sre.SRE_Match object; span=(0, 25), match='http://weibo.com/comment/'> # <_sre.SRE_Match object; span=(0, 31), match='http://weibo.com/comment/kEraCN'> kEraCN ``` 观察到`.*?`没有匹配到任何结果,而`.*`则尽量匹配多的内容,成功得到了匹配结果。 所以在这里好好体会一下贪婪匹配和非贪婪匹配的原理,对后面写正则表达式非常有帮助。 ## 修饰符 正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。 ```python content = '''Hello 1234567 World_This is a Regex Demo''' result1 = re.match(r'^He.*?(\d+).*?Demo', content) print(result1) # None ``` 和上面的例子相仿,在字符串中加了个换行符,正则表达式也是一样的来匹配其中的数字,但正则表达式没有匹配到这个字符串,返回结果为None,而又调用了group()方法所以导致AttributeError。 那加了一个换行符为什么就匹配不到了呢?是因为`.`匹配的是除换行符之外的任意字符,当遇到换行符时,`.*?`就不能匹配了,所以导致匹配失败。 那么在这里只需要加一个修饰符`re.S`,即可修正这个错误。在match()方法的第三个参数传入re.S,它的作用是使.匹配包括换行符在内的所有字符。 ```python result2 = re.match(r'^He.*?(\d+).*?\n.*?Demo', content) print(result2) # <_sre.SRE_Match object; span=(0, 41), match='Hello 1234567 World_This \nis a Regex Demo'> print(result2.group(1)) # 1234567 result3 = re.match(r'^He.*?(\d+).*?Demo', content, re.S) print(result3) # <_sre.SRE_Match object; span=(0, 41), match='Hello 1234567 World_This \nis a Regex Demo'> print(result3.group(1)) # 1234567 ``` 这个`re.S`在网页匹配中会经常用到,因为HTML节点经常会有换行,加上它就可以匹配节点与节点之间的换行了。 另外还有一些修饰符,在必要的情况下也可以使用: |修饰符|描述| |---|---| |re.I|使匹配对大小写不敏感| |re.L|做本地化识别(locale-aware)匹配| |re.M|多行匹配,影响 `^` 和 `$`| |re.S|使 `.` 匹配包括换行在内的所有字符| |re.U|根据Unicode字符集解析字符。这个标志影响 `\w`, `\W`, `\b`, `\B`| |re.X|该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。| 在网页匹配中较为常用的为re.S、re.I。 ## 转义匹配 正则表达式定义了许多匹配模式,如`.`匹配除换行符以外的任意字符,但是如果目标字符串里面它就包含`.`该怎么匹配? 那么这里就需要用到转义匹配了: ```python content = '(百度)www.baidu.com' result1 = re.match(r'(百度)www.baidu.com', content) print(result1) # None result2 = re.match(r'\(百度\)www\.baidu\.com', content) print(result2) # <_sre.SRE_Match object; span=(0, 17), match='(百度)www.baidu.com'> result3 = re.match(r'\((\w+)\)www\.baidu\.com', content) print(result3, result3.group(1)) # <_sre.SRE_Match object; span=(0, 17), match='(百度)www.baidu.com'> 百度 ``` 当遇到用于正则匹配模式的特殊字符时,在前面加反斜线来转义一下就可以匹配了。例如`.`就可以用`\.`来匹配,可以看到成功匹配到了原字符串。 ## search() `match()`方法是从字符串的开头开始匹配,一旦开头不匹配,那么整个匹配就失败了。 ```python content = 'Extra stings Hello 1234567 World_This is a Regex Demo Extra stings' result1 = re.match(r'Hello.*?(\d+).*?Demo', content) print(result1) # None result2 = re.search(r'Hello.*?(\d+).*?Demo', content) print(result2, result2.group(1)) # <_sre.SRE_Match object; span=(13, 53), match='Hello 1234567 World_This is a Regex Demo'> 1234567 ``` 在这里有一个字符串,它是以`Extra`开头的,但是正则表达式是以`Hello`开头的,整个正则表达式是字符串的一部分,但是这样匹配是失败的,也就是说只要第一个字符不匹配整个匹配就不能成功 所以`match()`方法在在使用的时候需要考虑到开头的内容,所以在做匹配的时候并不那么方便,它适合来检测某个字符串是否符合某个正则表达式的规则。 所以在这里就有另外一个方法`search()`,它在匹配时会扫描整个字符串,然后返回第一个成功匹配的结果,也就是说,正则表达式可以是字符串的一部分,在匹配时,`search()`方法会依次扫描字符串,直到找到第一个符合规则的字符串,然后返回匹配内容,如果搜索完了还没有找到,那就返回`None`。 把上面的代码中的`match()`方法修改成`search()`,这样就得到了匹配结果。 所以说,为了匹配方便,可以尽量使用`search()`方法。 下面再用几个实例来感受一下`search()`方法的用法。 首先这里有一段待匹配的HTML文本,接下来写几个正则表达式实例来实现相应信息的提取。 ```html html = '''<div id="songs-list"> <h2 class="title">经典老歌</h2> <p class="introduction"> 经典老歌列表 </p> <ul id="list" class="list-group"> <li data-view="2">一路上有你</li> <li data-view="7"> <a href="/2.mp3" singer="任贤齐">沧海一声笑</a> </li> <li data-view="4" class="active"> <a href="/3.mp3" singer="齐秦">往事随风</a> </li> <li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li> <li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li> <li data-view="5"> <a href="/6.mp3" singer="邓丽君"><i class="fa fa-user"></i>但愿人长久</a> </li> </ul> </div>''' ``` 观察到`<ul>`节点里面有许多`<li>`节点,其中`<li>`节点有的包含`<a>`节点,有的不包含`<a>`节点,`<a>`节点还有一些相应的属性,超链接和歌手名。 首先尝试提取`class`为`active`的`<li>`节点内部的超链接包含的歌手名和歌名。 所以需要提取第三个`<li>`节点下的`<a>`节点的`singe`r属性和文本。 所以正则表达式可以以`<li>`开头,然后接下来寻找一个标志符`active`,中间的部分可以用`.*?`来匹配,然后接下来要提取`singer`这个属性值,所以还需要写入`singer="(.*?)"`,需要提取的部分用小括号括起来,以便于用`group()`方法提取出来,它的两侧边界是双引号,然后接下来还需要匹配`<a>`节点的文本,那么它的左边界是`>`,右边界是`</a>`,所以指定一下左右边界,然后目标内容依然用`(.*?)`来匹配,所以最后的正则表达式就变成了`<li.*?active.*?singer="(.*?)">(.*?)</a>'`,然后再调用`search()`方法,它便会搜索整个HTML文本,找到符合正则表达式的第一个内容返回。 另外由于代码有换行,所以这里第三个参数需要传入`re.S` 所以整个匹配代码如下: ```python result1 = re.search(r'<li.*?active.*?singer="(.*?)">(.*?)</a>', html, re.S) print(result1) # <_sre.SRE_Match object; span=(153, 366), match='<li data-view="2">一路上有你</li>\n <li data-vi> print(result1.group(1), result1.group(2)) # 齐秦 往事随风 ``` 可以看到这个正是想提取的`class`为`active`的`<li>`节点内部的超链接包含的歌手名和歌名。 那么正则表达式不加`active`会怎样呢?也就是匹配不带`class`为`active`的节点内容,将正则表达式中的`active`去掉,代码改写如下,由于`search()`方法会返回第一个符合条件的匹配目标,那在这里结果就变了: ```python result2 = re.search(r'<li.*?singer="(.*?)">(.*?)</a>', html, re.S) print(result2) # <_sre.SRE_Match object; span=(153, 260), match='<li data-view="2">一路上有你</li>\n <li data-vi> print(result2.group(1), result2.group(2)) # 任贤齐 沧海一声笑 ``` 因为把`active`标签去掉之后,从字符串开头开始搜索,符合条件的节点就变成了第二个`<li>`节点,后面的就不再进行匹配,所以运行结果自然就变成了第二个`<li>`节点中的内容。 注意在上面两次匹配中,`search()`方法的第三个参数都加了`re.S`,使得`.*?`可以匹配换行,所以含有换行的`<li>`节点被匹配到了,如果将其去掉,结果会是什么? ```python result3 = re.search(r'<li.*?singer="(.*?)">(.*?)</a>', html) # 去掉匹配换行符参数 print(result3) # <_sre.SRE_Match object; span=(389, 448), match='<li data-view="6"><a href="/4.mp3" singer="beyond> if result3: print(result3.group(1), result3.group(2)) # beyond 光辉岁月 ``` 可以看到结果就变成了第四个`<li>`节点的内容,这是因为第二个和第三个`<li>`标签都包含了换行符,去掉`re.S`之后,`.*?`已经不能匹配换行符,所以正则表达式不会匹配到第二个和第三个`<li>`节点,而第四个`<li>`节点中不包含换行符,所以成功匹配。 由于绝大部分的HTML文本都包含了换行符,所以通过上面的例子,尽量都需要加上`re.S`修饰符,以免出现匹配不到的问题。 ## findall() 在前面说了`search()`方法的用法,它可以返回匹配正则表达式的第一个内容,但是如果想要获取匹配正则表达式的所有内容的话怎么办?这时就需要借助于`findall()`方法了。 `findall()`方法会搜索整个字符串然后返回匹配正则表达式的所有内容。 还是上面的HTML文本,如果想获取所有`<a>`节点的超链接、歌手和歌名,就可以将`search()`方法换成`findall()`方法。如果有返回结果的话就是list类型,所以需要遍历一下list来获依次获取每组内容。 ```python results = re.findall(r'<a.*?"(.*?)".*?singer="(.*?)">(.*?)</a>', html, re.S) print(results) for result in results: print(result[0], result[1], result[2]) 结果 [('/2.mp3', '任贤齐', '沧海一声笑'), ('/3.mp3', '齐秦', '往事随风'), ('/4.mp3', 'beyond', '光辉岁月'), ('/5.mp3', '陈慧琳', '记事本'), ('/6.mp3', '邓丽君', '<i class="fa fa-user"></i>但愿人长久')] /2.mp3 任贤齐 沧海一声笑 /3.mp3 齐秦 往事随风 /4.mp3 beyond 光辉岁月 /5.mp3 陈慧琳 记事本 /6.mp3 邓丽君 <i class="fa fa-user"></i>但愿人长久 ``` 可以看到,返回的list的每个元素都是`tuple`类型,用对应的索引依次取出即可。 所以,如果只是获取第一个内容,可以用`search()`方法,当需要提取多个内容时,就可以用`findall()`方法。 ## sub() 正则表达式除了提取信息,有时候还需要借助于它来修改文本,比如想要把一串文本中的所有数字都去掉,如果只用字符串的`replace()`方法那就太繁琐了,在这里就可以借助于`sub()`方法。 ```python content = '54aK54yr5oiR54ix5L2g' content = re.sub(r'\d+', '', content) print(content) # aKyroiRixLg ``` 在这里只需要在第一个参数传入`\d+`来匹配所有的数字,然后第二个参数是替换成的字符串,要去掉的话就可以赋值为空,第三个参数就是原字符串。 得到的结果就是替换修改之后的内容。 那么在上面的HTML文本中,如果想正则获取所有`<li>`节点的歌名,如果直接用正则表达式来提取可能比较繁琐,比如可以写成这样子: ```python results = re.findall('<li.*?>\s*?(<a.*?>)?(\w+)(</a>)?\s*?</li>', html, re.S) for result in results: print(result[1]) 结果 一路上有你 沧海一声笑 往事随风 光辉岁月 记事本 但愿人长久 ``` 但如果借助于`sub()`函数就比较简单了,可以先用`sub()`函数将`<a>`节点去掉,只留下文本,然后再利用`findall()`提取就好了。 ```python html = re.sub(r'<a.*?>|</a>|<i.*?/i>', '', html) print(html) results = re.findall(r'<li.*?>(.*?)</li>', html, re.S) for result in results: print(result.strip()) 结果 <div id="songs-list"> <h2 class="title">经典老歌</h2> <p class="introduction"> 经典老歌列表 </p> <ul id="list" class="list-group"> <li data-view="2">一路上有你</li> <li data-view="7"> 沧海一声笑 </li> <li data-view="4" class="active"> 往事随风 </li> <li data-view="6">光辉岁月</li> <li data-view="5">记事本</li> <li data-view="5"> 但愿人长久 </li> </ul> </div> 一路上有你 沧海一声笑 往事随风 光辉岁月 记事本 但愿人长久 ``` 可以到`<a>`标签在经过`sub()`函数处理后都没有了,然后再`findall()`直接提取即可。所以在适当的时候可以借助于`sub()`方法做一些相应处理可以事半功倍。 ## compile() 前面所讲的方法都是用来处理字符串的方法,最后再介绍一个`compile()`方法,这个方法可以讲正则字符串编译成正则表达式对象,以便于在后面的匹配中复用。 ```python content1 = '2016-12-15 12:00' content2 = '2016-12-17 12:55' content3 = '2016-12-22 13:21' pattern = re.compile('\d{2}:\d{2}') result1 = re.sub(pattern, '', content1) result2 = re.sub(pattern, '', content2) result3 = re.sub(pattern, '', content3) print(result1, result2, result3) # 2016-12-15 2016-12-17 2016-12-22 ``` 例如这里有三个日期,想分别将三个日期中的时间去掉,所以在这里可以借助于`sub()`方法,`sub()`方法的第一个参数是正则表达式,但是这里没有必要重复写三个同样的正则表达式,所以可以借助于`compile()`函数将正则表达式编译成一个正则表达式对象,以便复用。 另外`compile()`还可以传入修饰符,例如`re.S`等修饰符,这样在`search()`、`findall()`等方法中就不需要额外传了。所以`compile()`方法可以说是给正则表达式做了一层封装,以便于更好地复用。
很赞哦! (1)
相关文章
文章交流
- emoji