re模块

re模块

re模块提供了与 Perl 语言类似的正则表达式匹配操作


正则表达式

正则表达式(Regular Expression)是一种文本模式, 使用单个字符串来描述, 匹配一系列匹配某个句法规则的字符串.

普通字符

普通字符包括没有显式指定为元字符的所有可打印和不可打印字符. 这包括所有大写和小写字母, 所有数字, 所有标点符号和一些其他符号.

字符 描述
[ABC] 匹配[] 中的所有字符. 例如[aeiou] 匹配字符串"nohup python3.7 run.py" 中的o u字母
[^ABC] 匹配除了[] 中字符的所有字符, 例如[^aeiou] 匹配字符串"nohup python3.7 run.py" 中除了o u字母的所有字母
[A-Z] [A-Z] 表示一个区间,匹配所有大写字母, [a-z] 表示所有小写字母
. 匹配除换行符(\n, \r) 之外的任何单个字符, 相当于[^\n\r]
[\s\S] 匹配所有字符. \s是匹配所有空白符, 包括换行, \S是匹配非空白符, 不包括换行
\w 匹配字母, 数字, 下划线. 等价于[A-Za-Z0-9]
\W 匹配非字母, 数字, 下划线. 等价于[^A-Za-Z0-9]
\d 匹配一个数字字符. 等价于[0-9]
\D 匹配一个非数字字符. 等价于[^0-9]

非打印字符

字符 描述
\cx 匹配由x指明的控制字符. 例如, \cM匹配一个Control-M或回车符. x的值必须为A-Z或a-z之一, 否则将c视为一个原义的"c"字符
\f 匹配一个换页符. 等价于\x0c和\cL
\n 匹配一个换行符. 等价于\x0a和\cJ
\r 匹配一个回车符. 等价于\x0d和]cM
\s 匹配任何空白字符, 包括空格, 制表符, 换页符等等. 等价于[\f\n\r\t\v]
\S 匹配任何非空白字符. 等价于[^\f\n\r\t\v]
\t 匹配一个制表符. 等价于\x09和\cI
\v 匹配一个垂直制表符. 等价于\x0b和\cK

特殊字符

特殊字符就是一些有特殊含义的字符, 简单来说就是表示任何字符串的意思. 许多元字符要求在视图匹配它们的时候区别对待. 若要匹配这些特殊字符, 必须首先使用字符转义, 即将反斜杠字符\ 放在它们前面.

字符 描述
$ 匹配输入字符的结尾位置. 要匹配$字符, 请使用\$
^ 匹配输入字符的开始位置. 要匹配^字符, 请使用\^
() 标记一个子表达式的开始和结束位置. 子表达式可以获取后使用. 要匹配()字符, 请使用\(\)
* 匹配前面的子表达式零次或多次. 要匹配*字符, 请使用\*
+ 匹配前面的子表达式一次或多次. 要匹配+字符, 请使用\+
? 匹配前面的子表达式零次或一次, 或指明一个非贪婪限定符. 要匹配?字符, 请使用\?
. 匹配除换行符\n 之外的任何单字符. 要匹配.字符, 请使用\.
[ 标记一个中括号表达式开始. 要匹配[字符, 请使用\[
{ 标记限定符表达式的开始. 要匹配{, 请使用\{
| 指明两项之间的一个选择. 要匹配|, 请使用\|
\ 将下一个字符标记为特殊字符或原义字符或向后引用或八进制转义符

限定符

限定符用来指定前面表达式重复的次数.

字符 描述
* 匹配前面的子表达式零次或多次. 例如zo* 能匹配"z" 以及"zoo", 但不能匹配"zo". 等价于{0,}
+ 匹配前面的子表达式一次或多次. 例如zo+ 能匹配"zo"和"zoo", 但不能匹配"z". 等价于{1, }
? 匹配前面的子表达式零次或一次. 例如do(es)? 可以匹配"do", "does"中的"does"和"doxy"中的"do". 等价于{0,1}
{n} n是一个非负整数. 匹配确定的n次. 例如o{2} 能匹配"food"中的"oo", 但不能匹配"job"中的"o"
{n,} n是一个非负整数. 至少匹配n次. 例如o{2,} 能匹配"vooood"中的"oooo"
{n,m} n和m均为非负整数, 其中n <= m. 至少匹配n次且最多匹配m次. 例如o{1,3} 能匹配"zooooooom"中的"ooo". 注意在逗号和两个数之间不能有空格

定位符

定位符使你能够定位到行首或行尾, 也可以定位到单词内, 单词的开头或者单词的结尾.

字符 描述
^ 匹配字符串开始的位置
$ 匹配字符串结尾的位置
\b 匹配一个单词的边界, 即字与空格间的位置
\B 非单词边界匹配

非贪婪

在限定符后接? ,对前面的限定次数开启非贪婪模式, 意思就是在能匹配的前提下尽可能烧的重复匹配. 不接? 默认开启贪婪


re常用方法

  • re.compile(pattern, flags=0) 将正则表达式的样式编译为一个正则表达式对象(正则对象), 可以通过Pattern.math()Patterrn.search()方法用于匹配.

  • Pattern.match(string[,pos[,endpos]]) 如果string 的开始位置能匹配这个正则对象, 就返回一个相应的匹配对象. 如果不匹配, 就返回None .可选参数pos 给出了字符串开始搜索的索引位置, 默认为0. 可选参数endpos 限定了字符串结束搜索的索引位置.

  • Pattern.search(string[,pos[,endpos]]) 扫描整个string 寻找第一个匹配的对象, 并返回一个相应的匹配对象. 如果没有匹配, 就返回None . 可选参数同Pattern.math() .

    >>> pt = re.compile("\d+")
    >>> pt.match("as67df978asdfd7890asdf7890")
    >>> pt.search("as67df978asdfd7890asdf7890")
    <re.Match object; span=(2, 4), match='67'>
    >>> pt.match("as67df978asdfd7890asdf7890").group()
    Traceback (most recent call last):
      File "<input>", line 1, in <module>
    AttributeError: 'NoneType' object has no attribute 'group'
    >>> pt.search("as67df978asdfd7890asdf7890").group()
    '67'
    >>> pt.search("as67df978asdfd7890asdf7890").group()
    '67'
    >>> pt.match("as67df978asdfd7890asdf7890", 2)
    <re.Match object; span=(2, 4), match='67'>
    >>> pt.match("as67df978asdfd7890asdf7890", 2).group()
    '67'
    >>> pt.match("as67df978asdfd7890asdf7890", 6).group()
    '978'
    
    
  • re.match(pattern, string, flags=0) 如果string 的开始位置能够匹配pattern , 就返回一个相应的匹配对象. 如果没有匹配, 就返回一个None . 同re.compile() + Pattern.match() .

  • re.search(pattern, string, flags=0) 扫描整个string 寻找第一个匹配的pattern , 并返回一个相应的匹配对象. 如果没有匹配, 就返回None . 同re.compile() + Pattern.search() .

  • re.fullmatch(pattern, string, flags=0) 如果整个string 匹配到pattern , 就返回一个相应的匹配对象. 否则就返回一个None .

    >>> re.fullmatch('\d+','1234567').group()
    '1234567'
    >>> re.fullmatch('\w+','abcade').group()
    'abcade'
    
  • re.split(pattern, string, maxsplit=0, flags=0)pattern 分开string . 如果在pattern 中捕获到括号, 那么所有的组里的文字也会包含到列表里. 如果maxsplit 非零, 最多进行maxsplit 次分割, 剩下的字符全部返回到列表的最后一个元素.

    >>> re.split("\w", "hello world")
    ['', '', '', '', '', ' ', '', '', '', '', '']
    >>> re.split("\w+", "hello world")
    ['', ' ', '']
    >>> re.split("(\w+)", "hello world")
    ['', 'hello', ' ', 'world', '']
    
  • re.findall(pattern, string, flags=0) 以字符串或元组的列表形式返回string 中的所有非重复pattern . 从左到右扫描string , 并按找到的顺序返回pattern . 结果中包含空匹配项.

    >>> re.findall("\w+", "I have never been afraid to speculate on the Chinese with the worst malice")
    ['I', 'have', 'never', 'been', 'afraid', 'to', 'speculate', 'on', 'the', 'Chinese', 'with', 'the', 'worst', 'malice']
    >>> re.findall("\d+", "I have never been afraid to speculate on the Chinese with the worst malice")
    []
    
  • re.finditer(pattern, string, flags=0) 以一个迭代器形式返回string 里所有的非重复pattern . 从左到右扫描string , 按顺序返回pattern . 结果中包含空匹配项.

    >>> re.finditer("[abc]", "I have never been afraid to speculate on the Chinese with the worst malice")
    <callable_iterator object at 0x00000189B844C490>
    >>> i = re.finditer("[abc]", "I have never been afraid to speculate on the Chinese with the worst malice")
    >>> next(i)
    <re.Match object; span=(3, 4), match='a'>
    >>> next(i)
    <re.Match object; span=(13, 14), match='b'>
    >>> next(i).group()
    'a'
    >>> next(i).group()
    'c'
    
  • re.sub(pqttern, repl, string, count=0, flags=0) 返回通过使用repl 替换在string 最左边非重叠出现的pattern 而获得的字符串. repl 可以是字符串或函数; 如为字符串, 则其中任何反斜杠转义序列都会被处理. 如为一个函数, 那它会对每个非重复的pattern 的情况调用. 可选参数count 是要替换的最大次数.

    >>> re.sub("\s", "___", "I have never been afraid to speculate on the Chinese with the worst malice", count=4)
    'I___have___never___been___afraid to speculate on the Chinese with the worst malice'
    >>> re.sub("\s", "___", "I have never been afraid to speculate on the Chinese with the worst malice")
    'I___have___never___been___afraid___to___speculate___on___the___Chinese___with___the___worst___malice'
    

可选参数flags 表示匹配模式, 常用的有, re.A / re.ASCII 表示让\w , \W , \b , \B , \d , \D , \s , \S 只匹配ASCII, 而不匹配Unicode; re.I / re.IGNORECASE 表示忽略大小写匹配; re.L / re.LOCALE 表示\w , \W , \b , \B 和大小写敏感由当前语言区域决定; re.M / re.MULTILINE 表示^ 匹配每一行的开始, $ 匹配每一行的结尾. re.S / re.DOTALL 表示让. 匹配任何字符, 包括换行符.

上一篇:设计模式的定义


下一篇:Java代码中如何判断一个字符串中是否包含特殊字符呢?