首先,先来谈一谈用python开发爬虫时为什么需要使用到正则表达式。我们知道,可以使用xpath或者css选择器来提取网页中标签的元素值,例如有一个标签为<p>中国移动13411001111</p>
此时使用xpath或者css选择器能够将“中国移动13411001111”这整个标签中的元素值提取出来,但是,如果只想要提取号码,不要文字,就需要使用正则表达式来处理了。
接下来开始谈一下正则表达式的使用。下面先列举一些常用的正则表达式特殊字符,再结合实例说明它们的使用:
1)^ $ * ? + {2} {2, } {2,5}
2)[] [^] [a-z] .
3) \s \S \w \W
4) [\U4E00-\U9FA5] ( ) \d
第一组为限定符,用来指定正则表达式的一个组件需要出现多少次才能够匹配。
例子:
import re
s = "helloworld"//原字符串
regex_str = "^h.*d$"//正则表达式
if re.match(regex_str, s):
print("sucess!")
简单解释下上述的正则表达式部分,^为字符串开头的标记,则^h表示该正则表达式要匹配的字符串以h开头。而$为字符串结尾的标记,d$ 则表示以d结尾
。中间的 . 匹配任意字符,而*则表示匹配它前面的字符任意多次(包括0次)。所以整句正则表达式的意思就是匹配以h开头,d结尾的字符串。
上面说到*代表匹配任意次数,而+则代表匹配一次及一次以上。来一个例子说明一下:
import re
s = "abbaab"//原字符串
regex_str = ".*(b.+a).*"//正则表达式
match_obj = re.match(regex_str, s)
if match_obj:
print(match_obj.group(1))
上述代码的输出结果为baa,因为b和a之间还有个a,能够匹配一次,满足+的含义。如果将原字符串换成 s = “abbab”,那么上面的正则表达式就匹配不到了。
而{2}表示匹配2次,{2,}则表示匹配两次以上,{2,5}表示的是匹配2次到5次,使用方法同上的+ 和 * ,都是放置在字符后面,指明字符出现的次数。
我个人觉得相对比较难以理解的是 ? 这个限定符,要理解这个限定符的使用,首先得先理解一下正则表达式默认的贪婪匹配模式。先举一个例子:
import re
s = "abbaab"//原字符串
regex_str = ".*(b.*a).*"//正则表达式
match_obj = re.match(regex_str, s)
if match_obj:
print(match_obj.group(1))
这个例子就是在默认的贪婪模式下的匹配,输出的结果是baa,那么什么是贪婪呢?在“abbaab”中,我们要打印出来的字符子串是以b开头,以a结尾的。“abbaab”中一共有三个b,在匹配到第一个b后,发现第二个b还能满足正则表达式的匹配,所以会继续向后匹配b,匹配到第二个b,对于第一个b的处理就是,直接略过。同样的对于a的匹配也是如此,在匹配到第二个a时,发现第三个a还能继续满足正则匹配,所以继续向右匹配第三个a,所以结果就是baa。我自己所理解的贪婪匹配就是,在原字符串中找到最后一个可以满足正则表达式的字符串。这么说还是有点抽象,简单地说,贪婪匹配可以看做是从右到左的匹配。在”abbaab”中,匹配".*(b.*a).*"
,我们从右向左匹配,先找到a的匹配,为最后一个a,即倒数第二个字符的位置,然后继续向前匹配b,为倒数第二个b,即倒数第四个字符,这样就得到了贪婪的匹配结果,为baa。
说完了默认贪婪匹配,再说回 ? 限定符的作用,?就是让正则匹配为非贪婪的模式,即从左向右匹配。先举个例子:
import re
s = "abbaab"//原字符串
regex_str = ".*?(b.*a).*"//正则表达式
match_obj = re.match(regex_str, s)
if match_obj:
print(match_obj.group(1))
上面的正则表达式在b的前面加了?,即让b字符为非贪婪匹配,从左到右,找到第一个b就不再继续贪婪,而由于a的前面没有加上?,还是贪婪匹配模式,故最终的匹配结果为bbaa。如果在a的前面也加了?,即".*?(b.*?a).*"
则最终结果就为bba,即从左到右分别匹配到第一个b和第一个a就返回。
接下来简单说明一下[]的作用。[]有三种用法:
1)[abc] 表示匹配a,b,c三个字符中的一个
2)[^1]表示除了1之外的字符,这里强调一下,在中括号中的特殊字符,如”* ^”等等,都变为了普通字符,没有特殊含义
3)[0-9],中括号中用一个区间来表示,匹配0-9中的任何一个数字
说完了[]再说说\s 和\S \w 和\W的用法。\s表示匹配空格,\S的意思与\s刚好相反,即非空格。\w匹配[a-zA-Z0-9_]即小写字母,大写字母,0-9和下划线。而\W的含义也与\w相反,为\w所表示的字符除外的字符。
[\U4E00-\U9FA5]表示的是汉字,\d表示的是数字。()代表提取子字符串,将要提取的子字符串用()括起来,然后后面提取时,使用group()方法,从外层到内层的()分别是1,2,… 。最后说一个”\”,代表的是转义字符,如果要在字符串中匹配一些特殊字符,如? + 等等,就需要使用转义符号,正则表达式中相应地写为\? +。
基本的正则表达式特殊字符算是总结地七七八八了,学习了一些基本的用法后也不会再对正则表达式感到畏惧了,但是要熟练掌握的话,还是需要多多练习。