python学习—Day22—python的正则表达式

来源:互联网 发布:怎么抓淘宝的数据包 编辑:程序博客网 时间:2024/06/05 20:39

正则表达式:

正则的学习对于之后学习使用爬虫有很大帮助,爬虫爬到的东西,很多都是不规则的,需要发现一些规律来得到想要的东西,这样就需要用到很多的正则来实现

如果返回的是json的字符串则还好使用json模块解决。不然如果涉及到筛选罗列要求时,就选哟正则来匹配。

正则匹配推荐网站:https://regex101.com。在线测试正则命令。

跟linux中的shell的正则也有相似的地方:

1)” . “点代表:匹配任意除换行符”\n“外的字符。在DOTALL模式中也能匹配换行符。

2)” \ “斜杠代表:转义符,使后一个字符改变原来的意思。如果字符串中有字符 * 需要匹配,可以使用 \* 或者字符集[*]。

3)”  \d “杠代表:数字[ 0-9 ],代表匹配任意数字。

4)” \D “杠D代表:非数字[ ^\d ],代表匹配任意非数字。

5)” \s “斜杠s代表:空白字符[ <空格> \t \r \n \f \v],代表匹配任意的空白字符。

6)” \S “斜杠S代表:非空白字符[ ^\s ],代表匹配任意的非空白字符。

7)” \w “斜杠w代表:单词字符[ A-Z a-z 0-9_ ],代表任意非空白字符。

8)” \W“斜杠W代表:非单词字符[ ^\w ],代表任意的空白字符

注释:这里 \s \S \w \W这几项对应的执行结果是一样滴

9)” * “ 星号代表:匹配前一个字符0或无限次。解释:意思是 * 前面的字符不存在也可以,或者存在无限次都可以。如果是想要匹配某字符串之后的所有字符则可以使用ab.* 来实现。并且,这里涉及到一个python与shell的区别:在shell中如果要匹配一个 ” XX.txt “ 的文件,可以直接使用 ”  *.txt  “来实现。但是在python开头直接使用 *  星号报错,需要使用 ”  .*.txt  “ 来实现。

10)” + “加号代表:匹配前一个字符一次或无限次,代表匹配的这个字符至少需要出现一个。

11) ” ? “问号代表:匹配前一个字符0次或者1次。匹配的字符最多出现一次。

12) ” {m} “代表:匹配前一个字符m次。 指定匹配字符出现的次数。

13) ” {m,n} “代表:匹配前一个字符m至n次。m和n可以省略,即若省略m,则匹配0至n次;若省略n,则匹配m至无限次。

14) ” ^ “代表:匹配字符串开头,在多行模式中匹配每一行的开头。\\多行模式需要使用re模块进行正则对象化(这么说应该没问题咳咳)

15) ” $ “代表:匹配字符串末尾,在多行模式中匹配每一行的末尾。

16) ” \A “代表:仅匹配字符串开头。非多行模式这个可以使用 ” ^ “代替使用,两者功能相仿。

17) ” \Z “代表:仅匹配字符串末尾。非多行模式这个可以使用 ” $ “代替使用,两者功能相仿。

18) ” \b “代表:匹配 \w 和 \W 之间(指 单位字符与非单词字符之间)。指特殊符号:例如  感叹号。

19) ” \B “代表:[ ^\b ]。\\好奇存在的意义!

20) ” | “ 代表: 左右表达式任意匹配一个。它总是先常识匹配左边的表达式,一旦成功匹配则跳过匹配右边的表达式。如果 |  没有被包括在 () 中,则它的范围是整个正则表达式。

21) ” (...) “ 代表:被括起来的表达式将作为分组,从表达式左边开始每遇到一个分组的左括号”(“,编号+1,另外,分组表达式作为一个整体,可以后接数量词。表达式中的 | 仅在该组中有效。

22)” ?P<name>... “ 代表:分组,除了原有的编号外再指定一个额外的别名。

23) ” \<numner> “ 代表:引用编号为<number>的分组匹配到的字符串。\\对应  21)条

24) ” (?P=name) “ 代表引用别名为<name>的分组匹配到的字符串。\\对应  22)条

举例:




re正则对象和正则匹配效率比较:正则匹配是:优先编译成正则对象,然后再匹配,这样程序的效率更高。

re模块,跟正则一起使用的。效率高。下列代码是通过不同手段进行1000000次匹配。

import timeitprint timeit.timeit(setup='''import re; reg = re.compile('<(?P<tagname>\w*)>.*</(?P=tagname)>')''', stmt='''reg.match('<h1>xxx</h1>')''', number=1000000)print timeit.timeit(setup='''import re''', stmt='''re.match('<(?P<tagname>\w*)>.*</(?P=tagname)>', '<h1>xxx</h1>')''', number=1000000)
0.328666831712 \\时间短是因为在代码中将正则写入reg变量,每次使用直接调用即可。正则对象的效率最高!
0.891130376664 \\这条命令则是每次都使用正则重新匹配。纯粹的正则匹配。

解释:timeit.timeit是用来统计程序执行的时间的,和明显第一个print的执行时间要比第二个的执行时间快好多,这个就是把正则表达是表示成正则对象最明显的好处。

咳咳,不太不懂上面的意思,则有下图:其实就是这么个意思。上面的命令就是对于两者的执行效率。命令中的\w*差不都等同于 .* 了



编译正则对象:re

仔细观察在正则书写的时候,前面会有个   r"  ,这里r表示raw的简及raw string 意思是原生字符,也就是说是这个字符串中间的特殊字符不用转义

比如你要表示‘\n’,可以这样:r'\n' 。但是如果你不用原生字符而是用字符串你得这样:‘\\n’

import rereg = re.compile(r'abc.*')print(type(reg))
 <type '_sre.SRE_Pattern'>\\返回值类型:正则对象。re里面的方法这里的reg也是可以用的。


这个方法是就是将字符串的正则表达式编译城正则对象,第二个参数flag是匹配模式,取值可以使用按位或者运算符“|”表示同时生效,比如:re.I | re.M,flag的可选值有:

re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同)【这个还算比较常用】

M(MULTILINE): 多行模式,改变'^'和'$'的行为

S(DOTALL): 点任意匹配模式,改变'.'的行为

L(LOCALE): 使预定字符类 \w \W \b \B \s\S 取决于当前区域设定

U(UNICODE): 使预定字符类 \w \W \b \B \s\S \d \D 取决于unicode定义的字符属性

X(VERBOSE):详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释。

a = re.compile(r"""\d +  # the integral part

                   \.    # the decimal point

                   \d *  # some fractional digits""",re.X)

b = re.compile(r"\d+\.\d*") \\ab两者等价。


原创粉丝点击