正则表达式的书写

首先是一些字符的含义:

  • ‘\w’ 表示数字字母下划线。
  • ‘\d’ 表示数字。
  • . 表示除了换行符以外的所有字符。
  • ‘\s’ 表示所有空格符
  • a|b 表示要么是 a,要么是 b。注意 a b 不一定是单个字符。
  • () 除了在 python 中表示组,在实际正则表达式中可以划定范围或优先级。比如搭配 | 来使用。
  • ^ 表示匹配开头
  • $ 表示匹配结尾。
  • ‘[]’ 表示该位置的字符为字符集(中括号括起来的部分)组成。可以用 [a-z] 表示字母 a 到字母 z。
  • [^…] 表示除了字符集中的字符。
  • \D, \S 分别表示小写字母的补集。

下面是一些修饰符:

  • ‘+’ 表示前面的字符出现一次或多次
  • ‘*’ 表示前面的字符出现 0 次或多次。
  • ‘{m}’ 表示前面的字符出现 m 次。
  • ‘?’ 表示一次或 0 次。
  • ‘{n,}’ 表示前一个字符出现大于等于 n 次
  • ‘{n,m}’ 表示前一个字符出现 n 次到 m 次。

最后是惰性匹配和贪婪匹配:

  • *? 表示能匹配到越少越好。
  • * 表示匹配越多越好。

例子:

  • text:100100100100100
  • pattern1: 1\d*0, answer: 100100100100100
  • pattern2: 1\d*?0 answer: 10, 10, 10, 10, 10, 五处匹配。

注解 1:对于上面的特殊字符,例如 +, *, |, \ 等等,匹配这些字符需要在前面加上 ‘\‘。对于这四个符号,即 \+, \*, \|, \

注解 2:小括号 () 可以理解为划定了一个子表达式,同样的,中括号 [] 表示一个中括号表达式,故中括号也算特殊字符。大括号自有其含义。

注解 3:菜鸟教程中提到:* 和 + 都是贪婪的。都可以通过 ? 来进行修饰。

注解 4:正则表达式的匹配不会考虑重叠部分,即两个不同的匹配区间不会有重叠。例如用 ‘a{2}’ 匹配 aaaaaaaaaa,结果会是 5 个匹配。

用 python 来处理正则表达式

需要用到的 python 自带的库 re,re 也是正则表达式的英文名称 regular expression。

以下的函数可以接受一个特殊的参数 flag

注解 5:flag 参数,起到一个标识符的作用,拥有一些特殊的功能或含义。例如,当 flag = re.S 的时候,表示正则表达式中的 ‘.’ 可以表示换行符。

  • re.findall()

接受两个参数,第一个是正则表达式(字符串),第二个是需要匹配的字符串(字符串)。返回一个元素是字符串的列表,表示所有可以匹配到的结果。

  • re.finditer()

接受两个参数,第一个是正则表达式(字符串),第二个是需要匹配的字符串(字符串)。返回一个迭代器,迭代器指向的对象是 re.MatchObject 类,而从此类中提取出匹配到的字符串需要调用 group() 方法。

  • re.compile()

表示对正则表达式进行预编译,返回一个 re.Pattern 类,这个类中包含 findall(), finditer() 等方法,可以去掉正则表达式参数。这样可以节省代码量与时间。

  • re.search()

接受两个参数,第一个是正则表达式(字符串),第二个是需要匹配的字符串(字符串)。返回一个 re.MatchObject 实例,只能返回可以匹配到的第一个结果。

  • re.match()

接受两个参数,第一个是正则表达式(字符串),第二个是需要匹配的字符串(字符串)。不一样的是,match() 函数强制从头开始匹配。等加入正则表达式前面加一个 ‘^’。

  • group()

返回一个字符串。除了返回匹配结果,group() 函数还用于返回匹配到的特殊部分。对于一个 re.MatchObject 实例,有两种方式:

  1. 对于正则表达式里的组,按照左括号从左往右的顺序从 1 开始进行编号。group(0) 即返回全部的匹配结果,group(1) 表示第一个括号里面的正则表达式匹配到的结果。例子如下:
1
2
3
4
5
6
7
8
9
10
11
import re
reg = "a(b(c))(d)e"
pat = re.compile(reg);
s = pat.match("abcde");
print(s);
print(s.group());
print(s.group(0));
print(s.group(1));
print(s.group(2));
print(s.group(3));
# print(s.group(4));

返回结果:

1
2
3
4
5
6
<re.Match object; span=(0, 5), match='abcde'>
abcde
abcde
bc
c
d

注解 6:上述代码实现最后一行如不注释会出错,因为括号只有 3 个。

  1. 除了数字编号,还可以对某一组进行自定义命名。格式如:’(?P…)’。例子如下:
1
2
3
4
5
6
import re
reg = "a(?P<nametest>b(c))(d)e"
pat = re.compile(reg);
s = pat.match("abcde");
print(s.group());
print(s.group("nametest"));

返回结果:

1
2
abcde
bc