文章目录
- 前言
- 一、行定位符
- 二、元字符
- 三、限定符
- 四、字符类
- 五、排除字符
- 六、选择字符
- 七、转义字符
- 八、分组
- 九、正则表达式语法
- 总结
前言
在处理字符串时,经常会有查找符合某些复杂规则的字符串的需求。比如用爬虫批量抓取某网站图片,要从抓下来的网页信息中提取出所有的图片地址如下图所示:
这时候正则表达式就派上了用场,正则表达式就是记录文本规则的代码,有了它,我们可以从海量数据里面精准筛选出需要的那部分内容。今天就详细来看看正则表达式中的特殊字符以及详细用法。
一、行定位符
行定位符就是用来描述字符串的边界,“^” 表示行的开始,“$” 表示行的结尾。比如:
^Ha
该表达式表示要匹配字符串的开头位置是 Ha,如 “Hangzhou is a very beautiful city” 可以匹配,而 “Your words are very funny, Ha” 则不匹配。但如果使用:
Ha$
后者可以匹配而前者不能匹配。如果要匹配的字符串可以出现在字符串的任意部分,那么可以写成下面的格式,这样两个字符串都能匹配上。
Ha
二、元字符
除了前面介绍的 “^” 和 “$” 外,正则表达式里还有更多的元字符,例如下面的正则表达式中就应用了元字符 “\b” 和 “\w”。
\ban\w*\b
上面的正则表达式用于匹配以字母 an 开头的字符串,先从字符串的开头 an 处开始匹配,接着是任意数量的字母或数字(\w*)。该表达式可以匹配 “anaconda” 和 “and246”,但不能与 “abandon” 匹配。更多常见元字符如下表所示:
元字符 | 说明 | 举例 |
. | 匹配除换行符以外的任意字符 | . 可以匹配 “acd\n8R\t” 中的 a、c、d、8、R、\t |
\w | 匹配字母、数字、下划线或汉字 | \w 可以匹配 “miO次9\nqw” 中的 “m、i、O、次、9、q、w”,但不能匹配 \n |
\W | 匹配除字母、数字、下划线或汉字以外的字符 | \W 可以匹配 “92d\nsc” 中的 \n,但不能匹配 “9、2、d、s、c” |
\s | 匹配单个的空白符(包括 Tab 键和换行符) | \s 可以匹配 “c\t8B” 中的 \t |
\S | 匹配除单个空白符(包括 Tab 键和换行符)以外的所有字符 | \S 可以匹配 “字we2\t90” 中的 “字、w、e、2、9、0” |
\b | 匹配单词的开始或结束,单词的分解符通常是空格,标点符号或者换行 | 在 “there were deserts where” 字符串中,\bw 与 were 中的 w 相匹配,但与 where 中的 w 不匹配 |
\d | 匹配数字 | \d 可以与 “dg34&” 中的 3、4 匹配 |
三、限定符
在上面例子中,使用(\w*)可以匹配任意数量的字母或数字。但如果想要匹配指定数量的数字,该如何表示呢?
正则表达式为我们提供了限定符(指定数量的字符) 来实现该功能。如匹配 11 位电话号码可使用如下表达式:
^\d{11}$
常用的限定符如下表所示:
限定符 | 说明 | 举例 |
? | 匹配前面的字符 0 次或 1 次 | Pyth?on,该表达式可以匹配 Python 和 Pyton |
+ | 匹配前面的字符 1 次或多次 | Py+thon,该表达式可以匹配的范围从 Python 到 Pyy…thon |
* | 匹配前面的字符 0 次或多次 | Pyt*hon,该表达式可以匹配的范围从 Pyhon 到 Pytt…hon |
{n} | 匹配前面的字符 n 次 | Pytho{3}n,该表达式只匹配 Pythooon |
{n,} | 匹配前面的字符至少 n 次 | Pytho{3,}n,该表达式可以匹配的范围从 Pythooon 到 Pythooo…n |
{n,m} | 匹配前面的字符最少 n 次,最多 m 次 | P{1,3}ython,该表达式可以匹配 Python、PPython、PPPython |
四、字符类
正则表达式查找数字和字母是很简单的,因为已经有了对应这些字符集合的元字符(如 “\d”、“\w”),但是如果要匹配没有预定义元字符的字符集合(比如只匹配元音字母a,e,i,o,u),应该怎么办?
很简单,只需要在方括号里列出它们就行了,像 [aeiou] 可以匹配任何一个英文元音字母,[.?!] 匹配标点符号(“.”,“?”,“!”),也可以轻松的指定一个范围,像 “[0-9]” 代表的含义与 “\d” 就是完全一致的:代表一位数字。同理,“[a-z0-9A-Z_]” 完全等同于 “\w”(如果只考虑英文的话)。
五、排除字符
在上面的字符类中列出的匹配符合指定字符集合的字符串。现在反过来,匹配不符合指定字符集合的字符串。正则表达式提供了 “^” 字符。这个元字符在上面出现过,表示行的开始。而这里将会放到方括号中,表示排除的意思。例如:
[^a-zA-Z]
该表达式用于匹配一个不是字母的字符。
六、选择字符
试想一下,如何匹配身份证号码?首先需要了解一下身份证号码的规则。身份证号码长度为 18 位,前 17 位为数字,最后一位是校验位,可能为数字或字符 X。
在上面的描述中,包含着条件选择的逻辑,这就需要使用选择字符(|)来实现。该字符可以理解为 “或”,匹配身份证的表达式可以写成如下方式:
(^\d{18}$)|(^\d{17})(\d|X|x)$
该表达式的意思是匹配 18 位数字,或者 17 位数字和最后一位。最后一位可以是数字,也可以是 X 或者 x。
七、转义字符
正则表达式中的转义字符(\)和 Python 中的大同小异,可以将字符本身的含义转成特定的含义,如果是特殊字符(比如 “.” “?” “\” 等)则转变为普通的字符。举一个 IP 地址的实例,用正则表达式匹配诸如 “127.0.0.1” 格式的 IP 地址。如果直接使用点字符,格式为:
[1-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}
这显然不对,因为 “.” 可以匹配一个任意字符。这时,不仅是127.0.0.1 这样的 IP,连 127a0b0c1 这样的字符串也会被匹配出来。所以在使用 “.” 时,需要使用转义字符(\)。修改后上面的正则表达式格式为:
[1-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
🌱 说明:括号在正则表达式中也算是一个元字符。
八、分组
通过上面的选择字符板块,大家对小括号的作用有了一定了解。小括号字符的第一个作用就是可以改变限定符的作用范围,如 “|” “*” “^” 等。例如下面的表达式中包含小括号。
(fruit|food)s
这个表达式的意思是匹配单词 fruits 或 foods,如果不使用小括号,那么就变成了匹配单词 fruit 和 foods 了。
小括号的第二个作用是分组,也就是子表达式。如 ([a-z]{1,3}){3},就是对分组 ([a-z]{1,3}) 进行重复操作。
九、正则表达式语法
在Python中使用正则表达式时,是将其作为模式字符串使用的。例如,将匹配不是字母的一个字符的正则表达式表示为模式字符串,可以使用下面的代码:
'[^a-zA-Z]'
而如果将匹配以字母 g 开头的单词的正则表达式转换为模式字符串,则不能直接在其两侧添加引号定界符,例如,下面的代码是不正确的。
'\bg\w*\b'
而是需要将其中的 “\” 进行转义,转换后的结果为:
'\\bg\\w*\\b'
由于模式字符串中可能包括大量的特殊字符和反斜杠,所以需要写为原生字符串,即在模式字符串前加 r 或 R。例如,上面的模式字符串采用原生字符串表示为:
r'\bg\w*\b'
🌱 说明:在编写模式字符串时,并不是所有的反斜杠都需要进行转换,没有特殊意义的就不用转。
总结
今天主要介绍了正则表达式的全部特殊字符和语法,里面牵涉的字符种类居多,建议大家不要强行记忆。在下一篇博客中会讲到Python中怎么实现正则表达式操作,学了之后就可以结合这篇博客中的众多字符用法进行实操。