ssh jsp做网站,互联网营销师挣的是谁的钱,网站怎么接入百度地图,北京网站建设推广服务题外话#xff1a;
《Pi Network 免费挖矿国外热门项目 一个π币大约值3元到10元》相信过去BTC的人#xff0c;信不信未来的PI#xff0c;了解一下#xff0c;唯一一个高度与之持平的项目 如果把BeautifulSopu比喻成通过线索一步步接近目标的侦探的话#xff0c;那么正则…题外话
《Pi Network 免费挖矿国外热门项目 一个π币大约值3元到10元》相信过去BTC的人信不信未来的PI了解一下唯一一个高度与之持平的项目 如果把BeautifulSopu比喻成通过线索一步步接近目标的侦探的话那么正则表达式就是牛逼哄哄的“天眼系统”只要提供一些目标的特征无论搜索范围多大只要存在那么一两个符合特征的目标全都会被它直接逮住。 特性
牛逼王
BS的爸爸我告诉你个秘密其实BeautifulSoup也是用正则实现的而且它find_all的参数里还能接收正则呢信息精确定位BeautifulSoup用的是节点定位可能会出现多个符合条件的节点却没有目标信息正则是直接针对目标信息以字符为单位匹配一次筛选出正确结果前提是写好正则能获取信息的部分有时候完整的信息不是你想要的你只想取它的某一部分正则能搞定BS只能先获取完整信息再分离。用途大着呢不要以为正则只能爬虫前后端都少不了正则你填个信息判断是否合法这都是正则总之学到赚到啊
劝退大王
这么强大的方法是不是看到都心动了不过强大是有代价的较难上手很难精通这两根大棒一下子锤走了不少初学者。当时学的我是这样的 抽象可读性差。为了逮住某个目标你可能要写一条长长的看到自己都头晕的正则表达式看上去就像乱码一样。举个栗子如果你要匹配一个ip地址正则表达式会是这样 匹配ip地址((?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d)) ——真·乱码 编写时出错率高新手很难一次写对需要不停地修改几次十几次才能pass大脑在颤抖难于优化优化好的正则能提高匹配速度然而你这新手还想优化能匹配对就很不错了正则暗中偷笑
如果有足够的自信和毅力不被正则击倒那就来吧。屁学正则还不是迟早的事
re 模块
python 自带模块直接导入即可。有匹配替换等方法。 思考了许久后笔者觉得还是先讲表达式规则好因为某些方法的理解是要了解表达式的。 下文的规则是完全版的花了很久写成分享给读者顺便当成自己的网上笔记。
如果你学正则只是单单用来爬虫的话你只要熟悉“字符匹配”“分组或转义”“预定字符集”“数量词”“非贪婪模式”和(?:)取消分组了解或干脆不学“边界匹配”“特殊构造”就行了。
如果你觉得正则是你未来工作的刚需的话推荐熟悉所有规则。
匹配规则pattern
规则其实是一个原字符串如r表达式/r表达式较正式的叫法是模式字符串。最后再说一句匹配以单个字符为单位除括号能把多个字符打包成分组整体来匹配表达式本质是字符串不要单引双引号里套单引双引号会出错。
字符匹配
任一字符(空格也算)——就是匹配这个字符某些字符因为在正则中有特殊用途需前加反斜杠转义如 [ { . | ( ) ^ * ? $.——英文句号匹配除换行符\n外的任意单个字符[]——匹配中括号里的任一字符与-结合还能表示范围内的任一字符中括号内的字符除\外会自动转义还有小心多个中括号嵌套错误[^]——中括号最前面加^,与[ ]反义,匹配一个不在中括号里的字符也可以用横杠-
r[abcd]#匹配一个a或b或c或d
r[0-9]#匹配一个0至9的数-的作用域是左右各一个字符
r[a-z] r[A-Z]#分别匹配a到z或A到Z的一个字母
r[12-89]#注意因为是单字符匹配,匹配的是12到8的数9即1到9的一个数不是12到89的数
r[{.|()^*?$\\]#匹配 { . | ( ) ^ * ? $ \中任一个,\要转义
r[^a-zA-Z]#匹配一个不是字母的字符
分组或转义
()——括号表达式分组第n组n123....99从左往右数并形成子表达式(?Pname)——拥有括号的功能但能为该分组再指定一个自定名字(?Pname)——引用分配过名字的分组但没有分组功能|——或左右规则任意匹配一个从左往右尝试匹配一旦成功就跳过后面的规则。|没被包在括号中间的话它的作用域是整个表达式被包的话作用域在括号内\——反斜杠后接功能字有符转义功能后接数字1到99有引用分组的功能后接某些字母又有特殊功能
rabc|def|ghi#匹配abc或def或ghi
rma(?:k|d)e#匹配make或made
r(abc)def\1#相当于r(abc)defabc,匹配abcdefabc
r(?Pokabc)f(?Pok)#为(abc)子组分配了“ok”的名字然后再引用匹配abcfabc
预定字符集
\d——匹配任一个数字0~9\D——匹配一个非数字字符与\d互补\s——匹配一个空白字符包括空格\t,\n,\r,\n,\f,\v\S——匹配一个非空白字符\w——匹配一个单词字符。unicode下匹配各种语言的单个字符单个数字和下横线。ASCII下匹配单个英文字母单个数字和下横线\W——匹配一个非单词字符
r\w #能匹配物语ものがたり中的物语ものがたり汉语日语的单字其他语言同理
数量词接在字符或子组后
{n}——作用于前一个字符或子表达式匹配它重复n次{min,max}——作用于前一个字符或子表达式匹配它重复重复多少次min~max次min和max可只写一个设置重复下限或上限但逗号不能省不写min时min默认为0*——星号作用于前一个字符或子表达式匹配它零次或多次——作用于前一个字符或子表达式匹配它至少一次?——作用于前一个字符或子表达式匹配它零次或一次
rz{3}#匹配zzz
rz{0,3}#匹配z或zz或zzz
r(?:abc){2}#对子表达式匹配两次匹配abcabc(?:)是一个用法不分组的意思详看后面
#星号加号问号同理
非贪婪模式
在数量词后接?对前面的数量词开启非贪婪模式意思就是在能匹配的前提下尽可能少的重复匹配。正则默认开启贪婪模式
r.#默认贪婪对于abcdef能匹配到abcdef整条因为.贪婪地把尖括号也匹配掉了
r.?#非贪婪对于abcdef能匹配到abc和def
边界匹配
^——放在表达式的最前面作用域是表达式在多行模式中在每一行匹配字符串开头多行模式要手动开启否则和\A没什么区别$——放在表达式的最后面作用域是表达式在多行模式中在每一行匹配字符串末尾多行模式要手动开启否则和\Z没什么区别\A——放在表达式的最前面作用域是表达式匹配字符串开头不能多行匹配\Z——放在表达式的最后面作用域是表达式匹配字符串末尾不能多行匹配\b——不匹配字符只匹配一个边界匹配\w和\W或\W和\w的边界单词字符和非单词字符的边界\B——不匹配字符只匹配一个边界与\b相反匹配\w和\w或\W和\W的边界
r^abc|^def#匹配abc开头或def开头开启了多行模式时对字符串abcd\ndefh能匹配出abcdef两个
rabc$|def$#匹配abc结尾或def结尾开启了多行模式时对字符串0abc\n0def能匹配出abcdef两个
r\Aabc#匹配abc开头因为不能多行匹配就算开启多行模式对字符串abcd\nabcd只能匹配到前面的abc
#\Z同理
r\w\b\W#匹配“单词字符非单词字符”的结构如a!,1%
#\B同理
特殊构造不作为分组,不被findall捕获 (?:)——取消括号的分组功能使其不会被findall方法捕获(?#)——#后写注释内容整个(?#)会被忽略A(?)——A之后的字符串需要匹配括号里的表达式A才会被匹配,一定用在表达式的最后A是表达式(?)内的表达式不会被匹配捕捉下同A(?!)——A之后的字符串需要不匹配括号里的表达式A才会被匹配一定用在表达式的最后(?)A——A之前的字符串需要匹配括号里的表达式A才会被匹配一定用在表达式的最前括号内的表达式需固定长度不能使用除{n}外的数量词(?!)A——A之前的字符串需要不匹配括号里的表达式A才会被匹配一定用在表达式的最前括号内的表达式需固定长度不能使用除{n}外的数量词
r(ab(?cde))#匹配后面是bcd的ab
ra(?!\d)#匹配后面不跟一串数字的a后括号可用所有数量词
r(?abc)de#匹配前面是abc的de
r(?!\d{3})a#匹配前面不是三个数字的a前括号可以用{n}但是不能用不定量的数量词 (?iLmsux)——放在表达式最前面为所在的表达式设置模式”i”, “L”, “m”, “s”, “u”, “x”它们不匹配任何字串对应python中re模块当中的(re.I, re.L, re.M, re.S, re.U, re.X)的6种模式,下面flag参数讲
r(?i)abc#“i”对应re.I忽略大小写模式能匹配AbcABCabc等
方法参数
相比于繁杂的规则方法则要简单多了常用的就这几个
re.search(pattern,string,flags0),返回第一个匹配的match对象内含匹配字符串的信息re.findall(pattern,string,flags0),返回所有匹配分组的字符串组成的列表没设置分组相当于整个表达式就是一个分组#如果表达式有多个分组会返回复杂的列表因此findall中的表达式通常只有一个分组 re.finditer(pattern,string,flags0)同findall功能但是返回的是迭代器
#分组为(abc),findall只捕捉被数字包起来的abc返回列表[abc,abc]
re.findall(r\d(abc)\d,1abc1,2abc2)
#整个表达式匹配abab加一个两位数(?:)取消了ab的分组,findall只捕捉abab加一个数返回列表[abab1,abab2]
re.findall(r((?:ab){2}\d)\d,abab11,abab22)
pattern re.compile(pattern,flags0),把规则打包返回如多次使用该规则相当与pattern和flag的合体当成pattern使用可免去设置flagsre.sub(pattern,repl,string,count0,flags)把匹配到的部分用指定字符串repl替换count设置替换次数默认为零替换所有
参数
pattern接收模式字符串即表达式也可以接收打包的规则string接收待匹配字符串如html文档 flags模式标签接受以下模式多个模式用“|”分开如 flagsre.I|re.M re.I re.IGNORECASE 忽略大小写re.L re.LOCALE 支持当前语言,为了支持多语言版本的字符集使用环境re.U re.UNICODE 使用w,W,b,B这些元字符时将按照UNICODE定义的属性re.M re.MULTILINE 开启多行模式re.S re.DOTALL 使.能匹配换行符\nre.X re.VERBOSE 可以忽略正则表达式中的空白和#号的注释,不匹配空格和#注释re.A 开启ASCII模式
match对象方法
列出常用方法下面的match是对象
match.group(id/name)id是分组序号1~99,name是分组的自定名字返回指定分组的字符串不传参数数是返回整条匹配字符串match.start(id/name),match.end(id/name),match.span(id/name),分别返回指定分组字符串在整个字符串中的开始位置结束位置范围。
正则慢慢学就行正则的使用后面会有实例让大家熟悉