广告做网站,注入漏洞网站源码,企业wordpress主题下载地址,网站优化防范导读#xff1a;正则在各语言中的使用是有差异的#xff0c;本文以 Python 3 为基础。本文主要讲述的是正则的语法#xff0c;对于 re 模块不做过多描述#xff0c;只会对一些特殊地方做提示。很多人觉得正则很难#xff0c;在我看来#xff0c;这些人一定是没有用心。其…导读正则在各语言中的使用是有差异的本文以 Python 3 为基础。本文主要讲述的是正则的语法对于 re 模块不做过多描述只会对一些特殊地方做提示。很多人觉得正则很难在我看来这些人一定是没有用心。其实正则很简单根据二八原则我们只需要懂 20% 的内容就可以解决 80% 的问题了。我曾经有几年几乎每天都跟正则打交道刚接手项目的时候我对正则也是一无所知花半小时百度了一下然后写了几个 demo就开始正式接手了。三年多时间我用到的正则鲜有超出我最初半小时百度到的知识的。1、正则基础1.1、基础语法(1)常用元字符语法描述\b匹配单词的开始或结束\d匹配数字\s匹配任意不可见字符(空格、换行符、制表符等)等价于[ \f\n\r\t\v]。\w匹配任意 Unicode 字符集包括字母、数字、下划线、汉字等.匹配除换行符(\n)以外的任意字符^ 或 \A匹配字符串或行的起始位置$ 或 \Z匹配字符串或行的结束位置(2)限定词(又叫量词)语法描述*重复零次或更多次重复一次或更多次?重复零次或一次{n}重复 n 次{n,}重复 n 次或更多次{n,m}重复 n 到 m 次(3)常用反义词语法描述\B匹配非单词的开始或结束\D匹配非数字\S匹配任意可见字符 [^ \f\n\r\t\v]\W匹配任意非 Unicode 字符集除 a、b、c 以外的任意字符(4)字符族语法描述[abc]a、b 或 c除 a、b、c 以外的任意字符[a-zA-Z]a 到 z 或 A 到 Z[a-d[m-p]]a 到 d 或 m 到 p即 [a-dm-p](并集)[a-z[def]]d、e 或 f(交集)[a-z[^bc]]a 到 z除了 b 和 c[ad-z](减去)[a-z[^m-p]]a 到 z减去 m 到 p[a-lq-z](减去)以上便是正则的基础内容下面来写两个例子看下s 123abc你好re.search(\d, s).group()re.search(\w, s).group()结果123123abc你好是不是很简单1.2、修饰符修饰符在各语言中也是有差异的。Python 中的修饰符修饰符描述re.A匹配 ASCII字符类影响 \w, \W, \b, \B, \d, \Dre.I忽略大小写re.L做本地化识别匹配(这个极少极少使用)re.M多行匹配影响 和re.S使 . 匹配包括换行符(\n)在内的所有字符re.U匹配 Unicode 字符集。与 re.A 相对这是默认设置re.X忽略空格和 # 后面的注释以获得看起来更易懂的正则。(1)re.A修饰符 A 使 \w 只匹配 ASCII 字符\W 匹配非 ASCII 字符。s 123abc你好re.search(\w, s, re.A).group()re.search(\W, s, re.A).group()结果123abc你好但是描述中还有 \d 和 \D数字不都是 ASCII 字符吗这是什么意思别忘了还有 全角和半角s # 全角数字re.search(\d, s, re.U).group()结果(2)re.M多行匹配的模式其实也不常用很少有一行行规整的数据。s aaa\r\nbbb\r\ncccre.findall(^[\s\w]*?$, s)re.findall(^[\s\w]*?$, s, re.M)结果[aaa\r\nbbb\r\nccc] # 单行模式[aaa\r, bbb\r, ccc] # 多行模式(3)re.S这个简单直接看个例子。s aaa\r\nbbb\r\ncccre.findall(^.*, s)re.findall(^.*, s, re.S)结果[aaa\r][aaa\r\nbbb\r\nccc](4)re.X用法如下rc re.compile(r\d # 匹配数字# 和字母[a-zA-Z], re.X)rc.search(123abc).group()结果123abc注意用了 X 修饰符后正则中的所有空格会被忽略包括正则里面的原本有用的空格。如果正则中有需要使用空格只能用 \s 代替。(5)(?aiLmsux)修饰符不仅可以代码中指定也可以在正则中指定。(?aiLmsux) 表示了以上所有的修饰符具体用的时候需要哪个就在 ? 后面加上对应的字母示例如下(?a) 和 re.A 效果是一样的s 123abc你好re.search((?a)\w, s).group()re.search(\w, s, re.A).group()结果是一样的123abc123abc1.3、贪婪与懒惰当正则表达式中包含能接受重复的限定符时通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。s aababre.search(a.*b, s).group() # 这就是贪婪re.search(a.*?b, s).group() # 这就是懒惰结果aababaab简单来说所谓贪婪就是尽可能 多 的匹配所谓懒惰就是尽可能 少 的匹配。*、、{n,} 这些表达式属于贪婪*?、?、{n,}? 这些表达式就是懒惰(在贪婪的基础上加上 ?)。2、正则进阶2.1、捕获分组语法描述(exp)匹配exp并捕获文本到自动命名的组里(?Pexp)匹配exp并捕获文本到名称为 name 的组里(?:exp)匹配exp不捕获匹配的文本也不给此分组分配组号(?Pname)匹配之前由名为 name 的组匹配的文本注意在其他语言或者网上的一些正则工具中分组命名的语法是 (?exp) 或 (?nameexp) 但在 Python 里这样写会报错This named group syntax is not supported in this regex dialect。Python 中正确的写法是(?Pexp)示例一分组可以让我们用一条正则提取出多个信息例如s 姓名张三性别男电话138123456789m re.search(姓名[:](\w).*?电话[:](\d{11}), s)if m:name m.group(1)phone m.group(2)print(fname:{name}, phone:{phone})结果name:张三, phone:13812345678示例二(?Pexp) 有时还是会用到的 (?Pname) 则很少情况下会用到。我想了一个 (?Pname) 的使用示例给大家看下效果s 张三30138123456789pattern r.*?)(.*?)(?Pname)It re.findall(pattern, s)结果[(name, 张三), (age, 30), (phone, 138123456789)]2.2、零宽断言语法描述(?exp)匹配exp前面的位置(?exp)匹配exp后面的位置(?!exp)匹配后面跟的不是exp的位置(?匹配前面不是exp的位置注意正则中常用的前项界定 (?exp) 和前项否定界定 (?(?aaa) # 正确(?aaa|bbb) # 正确(?aaa|bb) # 错误(?\d) # 错误(?\d{3}) # 正确2.3、条件匹配这大概是最复杂的正则表达式了。语法如下语法描述(?(id/name)yes|no)如果指定分组存在则匹配 yes 模式否则匹配 no 模式此语法极少用到印象中只用过一次。以下示例的要求是如果以 _ 开头则以字母结尾否则以数字结尾。s1 _abcds2 abc1pattern (_)?[a-zA-Z](?(1)[a-zA-Z]|\d)re.search(pattern, s1).group()re.search(pattern, s2).group()结果_abcdabc12.4、findallPython 中的 re.findall 是个比较特别的方法(之所以说它特别是跟我常用的 C# 做比较在没看注释之前我想当然的掉坑里去了)。我们看这个方法的官方注释Return a list of all non-overlapping matches in the string.If one or more capturing groups are present in the pattern, returna list of groups; this will be a list of tuples if the patternhas more than one group.Empty matches are included in the result.简单来说就是如果没有分组则返回整条正则匹配结果的列表如果有 1 个分组则返回分组匹配到的结果的列表如果有多个分组则返回分组匹配到的结果的元组的列表。看下面的例子s aaa123bbb456cccre.findall([a-z]\d, s) # 不包含分组re.findall([a-z](\d), s) # 包含一个分组re.findall(([a-z](\d)), s) # 包含多个分组re.findall((?:[a-z](\d)), s) # ?: 不捕获分组匹配结果结果[aaa123, bbb456][123, 456][(aaa123, 123), (bbb456, 456)][123, 456]零宽断言中讲到 Python 中前项界定必须是定长的这很不方便但是配合 findall 有分组时只取分组结果的特性就可以模拟出非定长前项界定的效果了。结语其实正则就像是一个数学公式会背公式不一定会做题。但其实这公式一点也不难至少比学校里学的数学简单多了多练习几次也就会了。