概念
正则表达式,又称规则表达式,简称为regex,是文本模式的表示方法。正则表通常被用来检索、替换那些符合某个模式(规则)的文本。
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
- 给定一个正则表达式和另一个字符串,我们可以达到如下的目的:
- 给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”);
- 可以通过正则表达式,从字符串中获取我们想要的特定部分。
- 正则表达式的特点是:
- 灵活性、逻辑性和功能性非常强;
- 可以迅速地用极简单的方式达到字符串的复杂控制。
- 对于刚接触的人来说,比较晦涩难懂。
用正则表达式查找文本模式
创建正则表达式对象
Python中所有正则表达式的函数都在re模块中。在使用时,用import
将其引入。向re.compile
中传入一个字符串值,表示正则表达式,它将返回一个Regex模式对象。
要创建一个Regex对象,就要输入以下代码:
1 |
|
在Python中,转义字符使用倒斜杠(\
)。字符串’\n’表示一个换行字符,而不是倒斜杠加上一个小写的n。你需要输入转义字符\\
,才能打印出一个倒斜杠。所以'\\n'
表示一个倒斜杠加上一个小写的n。但是,通过在字符串的第一个引号之前加上r,可以将该字符串标记为原始字符串,它不包括转义字符。
因为正则表达式常常使用倒斜杠,向re.compile()
函数传入原始字符串相对来说就比输入额外的倒斜杠方便,即输入r'\d\d\d'
比输入'\\d\\d\\d'
要容易得多。
匹配Regex对象
Regex对象的search()方法查找传入的字符串,寻找该正则表达式的所有匹配。如果字符串中没有找到该正则表达式,search()方法就会返回None。如果找到了该模式,search()方法将会返回一个Match对象。Match对象有一个group()方法,它返回被查找字符串中实际匹配的文本。下面是演示代码:
1 | import re |
这样,将会打印匹配到的415-555-4242
这个电话号码。
用正则表达式匹配更多模式
利用括号分组
假定我想要上面那个电话号码的区号,即将区号从电话号码中分离,可以添加括号使正则表达式分组:'(\d\d\d)-(\d\d\d-\d\d\d\d)'
。然后再使用group()方法匹配对象方法,从一个分组中获取匹配的文本。
正则表达式字符串中的第一对括号表示第一组。第二对括号表示第二组。向group()方法中传入整数1或2,就可以匹配文本的不同部分。向group()方法传入0或不传入参数,将返回整个匹配文本。下面是演示代码:
1 | import re |
这样将依次返回415-555-4242
、415
、555-4242
这三个结果。如果想一次就获得所有的分组,可以使用groups()这个方法,这样将会返回多个值得元组。
但是,括号在正则表达式中有特殊的含义,如果你要在文本中匹配括号的话,请在括号对前输入倒斜杠。即传递给re.compile()的原始字符串中,\(
和\)
转义字符将会匹配实际的括号字符。
用管道匹配多个分组
字符’|’称为管道。希望匹配许多表达式中的一个时,就可以使用它。例如正则表达式r'Batman|Tina'
将匹配Batman或Tina。
也可以使用管道来匹配多个模式的一个,作为正则表达式的一部分。例如,假设你希望匹配'Batman'
、'Batmobile'
、'Batcopter'
和'Batbar'
中任意一个,由于所有的这些字符串都以Bat开始,所以如果能够只指定一次前缀,就很方便。可以通过括号实现。下面是演示代码:
1 | import re |
这样将会打印Batmobile
和mobile
。方法group()返回了完全匹配的文本’Batmobile’,而group(1)只是返回第一个括号分组内匹配的文本’mobile’。通过使用管道字符和分组括号,可以指定几种可选的模式,让正则表达式去匹配。
如果需要匹配真正的管道字符,就用倒斜杠转义,即\|
。
用问号实现可选匹配
我们可以让匹配的模式是可选的。就是说,不论这段文本在不在,正则表达式都会认为匹配。字符?表明它前面的分组在这个模式是可选的。例如:
1 | import re |
正则表达式中的(wo)?
部分表明,模式wo是可选的分组。该正则表达式匹配的文本中,wo将出现零次或多次。
正则表达式用法总结
正则表达式还有许多表示法,就不一一全部演示了,这里给出常用的用法:
- ?匹配零次或一次前面的分组。
- *匹配零次或多次的分组。
- +匹配一次或多次前面的分组。
- {n}匹配n次前面的分组。
- {n,}匹配n次或更多次前面的分组。
- {,m}匹配零次到m次前面的分组。
- {n,m}匹配至少n次、至多m次前面的分组。
- {n,m}?或*?或+?对前面的分组进行非贪心匹配。
- ^begin意味着字符串必须以begin开头。
- end$意味着字符串必须以end结尾。
- .匹配所有字符,换行符除外。
\d
、\w
和\s
分别匹配数字、单词和空格。\D
、\W
和\S
分别匹配除数字、单词和空格以外的所有字符。- [abc]匹配方括号在内的任意字符,诸如a、b或c。
- abc匹配不在方括号内的任意字符。
正则表达式应用
利用正则表达式计算词频
我们可以利用正则表达式来操作数据,下面的代码是利用正则表达式给出网页中使用频率最高的十个词。
1 | import urllib.request |
最后得到结果:
1 | ('px', 1954) |