正则表达式(或RE)指定一组匹配它字符串;此模块中的函数让你检查一个特定的字符串是否匹配给定的正则表达式(或给定的正则表达式是否匹配特定的字符串,这可归结为同一件事)。
正则表达式可以连接以形成新的正则表达式;如果A和B两个都是正则表达式,那么AB也是正则表达式。一般来说,如果字符串p匹配A且另一个字符串q匹配B,那么字符串pq将匹配AB。除非A或B包含低优先级的操作;A和B之间存在边界条件;或有编号的组的引用。因此,复杂的表达式可以轻松地从这里所描述的更简单的原始表达式构建。关于理论的细节及正则表达式的实现,请参阅上文引用的Friedl的书或任何一本有关编译器构造的教科书。
下面简要说明了正则表达式的格式。进一步的信息和更友好的演示,请参阅正则表达式HOWTO。
正则表达式可以包含特殊和普通字符。最普通的字符,如'A'、'a'、或'0'是最简单的正则表达式;它们简单地匹配它们自己。你可以连接普通字符,所以last匹配字符串'last'。(在本节剩下的部分,我们将把正则表达式写成不带引号的形式这种独特风格,要匹配的字符串写成带引号的形式'用单引号'。)
某些字符,比如'|'或'(',比较特殊。特殊字符要么表示某个类别的普通字符,要么影响它们周围的正则表达式如何解释。正则表达式的模式字符串不可以包含空字节,但可以使用\number符号指定空字节,例如'\x00'。
特殊字符有:
-
'.'
- (点号。)在默认模式下,匹配除换行以外的任意字符.如果 DOTALL 标志被指定, 则匹配包括换行符在内的所有字符. '^'
- (脱字符号。)在默认模式下匹配字符串的起始位置, 在MULTILINE模式下也匹配换行符之后的位置. '$'
- 匹配字符串的末尾或者字符串末尾换行符之前的位置,在MULTILINE模式下还匹配换行符之前的位置。foo既匹配‘foo’也匹配‘foobar’,但是foo$只匹配‘foo’。更有趣的是,正常情况下foo.$只匹配'foo1\nfoo2\n' ‘foo2’,但是在MULTILINE模式下还能匹配‘foo1’;在'foo\n'中搜索单个$将找到两个(空的)匹配:一个是换行符之前,一个是字符串的末尾。 '*'
- 匹配前面重复出现的正则表达式零次或多次,尽可能多的匹配。ab*将匹配‘a’、‘ab’或‘a’ 后面跟随任意数目的‘b’。 '+'
- 引起生成的RE匹配1个或多个前导的RE,尽可能多的匹配。ab+将匹配‘a’之后跟随任意多个数目不为零的‘b’,它将不能匹配单纯的一个‘a’。 '?'
- 引起生成的RE匹配0个或1个前导的RE。ab?将匹配‘a’或者‘ab’。 *?, +?, ??
- '*'、'+'和'?'限定符是贪婪的; 它们匹配尽可能多的文本。有时这个行为不是想要的;如果用正则表达式<.*>来匹配'<H1>title</H1>',它将匹配完整的字符串,而不会只是'<H1>'。在限定符之后加上'?'将使得匹配以非贪婪的或最小的方式进行;因为它将匹配尽可能少的字符。在刚才的表达式中使用.*?将只匹配'<H1>'。 {m}
- 表示精确匹配前面的正则表达式的m个拷贝;较少的匹配将导致整个表达式不能匹配。例如,a{6}将精确匹配6个'a'字符,5个将不能匹配。 {m,n}
- 引起生成的正则表达式匹配前导正则表达式的m到n个重复,尝试匹配尽可能多的重复。例如,a{3,5}将匹配3到5个'a'字符。省略m表示下界为0,省略n表示上界无限大。举个例子,a{4,}b将匹配aaaab或一千个'a'字符后跟随一个b,但不能匹配aaab。逗号不可以省略,否则该修改符将与前面的形式混淆。 {m,n}?
- 例如,对于6个字符的字符串'aaaaaa',a{3,5}将匹配5个'a'字符,而a{3,5}?将只匹配3个字符。 '\'
-
对任一特殊字符进行转义(允许您匹配字符(如'*',' ? ',等等),或只是一个特殊的序列;特殊序列在下面讨论。
如果你不使用原始字符串来表达模式,记住在字符串字面值中Python也使用反斜杠作为转义序列;如果转义序列不能被Python解析器识别,那么结果字符串中包含反斜杠和后面的字符。但是,如果Python会识别所产生的序列,反斜杠应该重复两次。这比较复杂和难以理解,因此强烈建议你为所有即使是最简单的表达式使用原始字符串。
[]
-
用来表示一个字符集合。在一个集合中:
- 字符可以一个一个列出来,例如[amk]将匹配'a'、'm'或'k'。
- 通过给出两个字符并用'-'分隔,可以给出一段范围的字符,例如[a-z]将匹配任意一个小写的ASCII字符,[0-5][0-9]将匹配00到59之间所有的两位数字,[0-9A-Fa-f]将匹配任意一个十六进制数字。如果-被转义(例如[a\-z])或者如果它位于第一个或最后一个字符(例如[a-]),它将只匹配一个字面值'-'。
- 在集合内部,特殊字数将失去它们特殊的含义。例如,[(+*)]将匹配字符字面值'('、'+'、'*'或')'。
- 在集合中还接受字符类别,例如\w或\S(在下文定义),尽管它们匹配的字符取决于LOCALE或UNICODE模式是否是强制的。
- 不在一段范围之内的字符可以通过补集匹配。如果集合的第一个字符是'^',那么所有不在集合中的字符都将被匹配。例如,[^5]将匹配除'5'之外的所有字符,[^^]将匹配除'^'之外的所有字符。^如果不是集合中的第一个字符则没有特殊的含义。
- 若要匹配集合中的一个字符字面值']',可以在它前面放一个反斜线或者将它放在集合的开始。例如,[()[\]{}]和[]()[{}]都将匹配一个圆括号。
'|'
- A|B, 此处的 A 和 B 可以是任意的正则表达式, 创建的这个正则表达式要么匹配 A 要么匹配 B. '|'可以用来隔开任意个数的正则表达式,着同样可以用在组里面。 当扫描字符串时,REs 被用'|'从左到右分隔。当一个模式被完全匹配时,这个被匹配的模式就被接受。这意味着一旦 匹配A , B 就不在被尝试, 即使他会产生更长的整体匹配. 换句话说, '|' 不是贪婪操作符. 匹配符号 '|',用 |, 或者把它包含在组内, 就像是 [|]. (...)
- 匹配任何在圆括号内的正则表达式, 并表明分组的开始和结束; 分组的内容在完成匹配后可以提取出来,而且可以在后面的字符串中用特殊的number序列匹配,下面有描述。若要匹配字面值'('或')',请使用( or ),或它们放入字符类的括号中:[(] [)]。 (?...)这是一个扩展符号(a'?“遵循a”(否则就没有意义)。第一个角色是“?”确定构造的意义和进一步的语法是什么。扩展通常不会创建一个新的组;(P.)是这条规则的唯一例外。 下面是目前支持的扩展。 (?iLmsux)
-
(集合'i', 'L', 'm', 's', 'u', 'x'中的一个或多个字母。)这个分组空字符串;这些字母给真个正则表达式设置相应的标记:
re.I
(忽略大小写),re.L
(依赖区域设置),re.M
(多行),re.S
(点号匹配所有字符),re.U
(依赖Unicode),re.X
(详细模式)。(这些标志在模块的内容中讲述)。它用于如果你想要包含这些标志作为正则表达式的一部分,而不是将flag参数传递给re.compile()函数。请注意,(?x)标志更改解析表达的方式。它应使用在表达式字符串的开始,或一个或多个空白字符之后。如果在这个标志之前有非空白字符,结果是未定义的。
(?:...)
- 括号形式的正则表达式的非匹配版本。匹配括号中的任何正则表达式,但是匹配的子字符串不能在匹配后提取或在模式中引用。 (?P<name>...)
-
通过符号组名称name可以访问类似于常规的括号,但由组匹配的子字符串。组名必须是有效的 Python 标识符,并且每个组名必须在正则表达式内只有一次定义。海员象征性的组织也是带编号的组,就好像组未被命名。
命名组可以在三个上下文中引用。如果模式是(P.P')。(P=引号)(例如,匹配一个单引号或双引号的字符串):
参照组"引用"引用的方式 引用方法 在相同的模式中 - (?P=quote) (as shown)
- \1
当处理匹配对象m时 - m.group('quote')
- m.end('quote') (etc.)
在传递给re.sub()的repl参数的字符串中 - \g<quote>
- \g<1>
- \1
(?P=name)
- A backreference to a named group; 反向关联一个已被命名的字符串组。 它将匹配之前被关联到name中的所有内容。 (?#...)
- 一条注释;圆括号内容可简单忽略。 (?=...)
- 如果匹配……下一个匹配,但不消耗任何字符串。这被称为“先行断言”。例如,Isaac(?=Asimov)只有在“Asimov”之后才会与“Isaac”相匹配。 (?!...)
- 如果匹配……不匹配。这是一个负先行断言。例如,Isaac(?!Asimov)只有在没有“Asimov”的情况下才会与“Isaac”相匹配。 (?<=...)
-
如果在字符串中的当前位置之前由...匹配项的比赛,在当前的位置结束。这就被所谓的积极回顾后发断言。 (? < = abc) def将发现一个匹配abcdef,因为预测先行将备份 3 个字符,并检查是否包含的模式匹配。包含的模式必须只匹配固定长度的字符串,这意味着允许abc 或a|b 的,但a* 和a{3,4} 不允许。请注意,开始与正预测先行断言的模式将不匹配开头的字符串被搜查 ;您将最有可能想要使用search ()函数,而不是match ()函数:
>>> import re >>> m = re.search('(?<=abc)def', 'abcdef') >>> m.group(0) 'def'
本示例查看后面一个连字符的词:
>>> m = re.search('(?<=-)\w+', 'spam-egg') >>> m.group(0) 'egg'
(?<!...)
-
如果字符串的当前位置不匹配之前的 .... 这叫做 否定性回顾断言. 类似于断言的正面的断言,所包含的模式必须只匹配一些固定长度的字符串。从负面的look后面断言开始的模式可能在被搜索的字符串的开头处匹配。
(?(id/name)yes-pattern|no-pattern)
-
如果有给定的id或名称的组存在,并且没有模式,则将尝试与yes-pattern匹配。无模式是可选的,可以省略。例如,(<)?(w+@w+(?:w+)+)(?(1))是一个糟糕的电子邮件匹配模式,它将与“user@host.com”以及“user@host.com”相匹配,而不是“user@host.com”。
在 2.4 版本新。
-
\number
- 匹配同一号码组的内容。组从1开始编号。例如,(。+)1匹配“the”或“55”,而不是“thethe”(注意组后面的空格)。这个特殊的序列只能用于匹配前99个组中的一个。如果数字的第一个数字是0,或者数字是3个八进制数字,那么它就不会被解释为组匹配,而是作为具有八进制值的字符。在一个字符类的“and”中,所有的数字转义都被视为字符。 \A
- 只在字符串的开始处匹配。 \b
- 匹配空字符串,但仅在单词的开头或结尾。单词被定义为字母数字或下划线字符的序列,因此单词的结尾是由空格或非字母数字、非下划线字符表示的。请注意,形式上,被定义为W和W字符之间的边界(反之亦然),或者W和字符串的开始/结束之间的界限,因此被认为是字母数字的精确的字符集合取决于UNICODE和地区标志的值。例如,r'bfoo b'匹配'foo','foo。“(foo)”,“bar foo baz”,但不是“foobar”或“foo3”。在一个字符范围内,代表backspace字符,以与Python的字符串字面量兼容。 \B
- 匹配空字符串,但只有当它不在一个单词的开始或结束时。这意味着r'py B'匹配'python','py3','py2',但不是'py','py。”,或“py !”。B与B正好相反,所以也要服从地区和UNICODE的设置。 \d
- 当没有指定UNICODE标志时,匹配任何十进制数字;这相当于0-9。使用UNICODE,它将匹配UNICODE字符属性数据库中的十进制数字。 \D
- 当没有指定UNICODE标志时,匹配任何非数字字符;这相当于0-9。有了UNICODE,它将匹配UNICODE字符属性数据库中标记为数字的字符。 \s
- 当没有指定UNICODE标志时,它与任何空白字符相匹配,这就相当于set tnr f v。场所标志对空间的匹配没有额外的影响。如果UNICODE被设置,那么它将匹配字符t n r f v加上在UNICODE字符属性数据库中被归类为空格的内容。 \S
- 当没有指定UNICODE标志时,匹配任何非空白字符;这等价于集合t n r f v。场所标志对非空白匹配没有额外的影响。如果UNICODE被设置,那么在UNICODE字符属性数据库中不标记为空格的任何字符都是匹配的。 \w
- 当没有指定场所和UNICODE标志时,匹配任何字母数字字符和下划线;这等价于集合a-za-z0-9。使用LOCALE,它将匹配0-9的设置,以及当前地区所定义的字母数字字符。如果设置了UNICODE,它将匹配0-9的字符,以及在UNICODE字符属性数据库中被归类为字母数字的任何东西。 \W
- 当没有指定场所和UNICODE标志时,匹配任何非字母数字字符;这等价于集合a-za-z0-9。对于locale,它将匹配0-9中没有的任何字符,并且没有定义为当前地区的字母数字。如果设置了UNICODE,那么它将匹配除0-9 plus字符以外的任何其他字符,而不是UNICODE字符属性数据库中的字母数字。 \Z
- 只在字符串的结尾处进行匹配
如果区域设置和UNICODE标志包括为一个特定的序列,区域设置标志可将第一次跟着UNICODE的生效。
由正则表达式分析器也接受大多数支持通过 Python 字符串的标准转义:
\a \b \f \n
\r \t \v \x
\\
(请注意,用来表示单词边界,并意味着"退格键"只能在字符类的内部。)
八进制转义中有限的形式包括: 如果第一个数字为 0,或者如果有三个八进制数字,它被认为是八进制转义符。否则,它是组引用。字符串文本总是八进制转义顶多是三个数字的长度。
很多不太懂正则的朋友,在遇到需要用正则校验数据时,往往是在网上去找很久,结果找来的还是不很符合要求。
所以我最近把开发中常用的一些正则表达式整理了一下,包括校验数字、字符、一些特殊的需求等等。
给自己留个底,也给朋友们做个参考。
一、校验数字的表达式
数字:^[0-9]*$
n位的数字:^\d{n}$
至少n位的数字:^\d{n,}$
m-n位的数字:^\d{m,n}$
零和非零开头的数字:^(0|[1-9][0-9]*)$
非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$
带1-2位小数的正数或负数:^(\-)?\d+(\.\d{1,2})?$
正数、负数、和小数:^(\-|\+)?\d+(\.\d+)?$
有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
有1~3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
非零的正整数:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
非零的负整数:^\-[1-9][]0-9″*$ 或 ^-[1-9]\d*$
非负整数:^\d+$ 或 ^[1-9]\d*|0$
非正整数:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
非负浮点数:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
非正浮点数:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
正浮点数:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
负浮点数:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
浮点数:^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
二、校验字符的表达式
汉字:^[\u4e00-\u9fa5]{0,}$
英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
长度为3-20的所有字符:^.{3,20}$
由26个英文字母组成的字符串:^[A-Za-z]+$
由26个大写英文字母组成的字符串:^[A-Z]+$
由26个小写英文字母组成的字符串:^[a-z]+$
由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$
中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$
中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
可以输入含有^%&',;=?$\”等字符:[^%&',;=?$\x22]+
禁止输入含有~的字符:[^~\x22]+
三、特殊需求表达式
Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
手机号码:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$
电话号码(“XXX-XXXXXXX”、”XXXX-XXXXXXXX”、”XXX-XXXXXXX”、”XXX-XXXXXXXX”、”XXXXXXX”和”XXXXXXXX):^($$\d{3,4}-)|\d{3.4}-)?\d{7,8}$
国内电话号码(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}
身份证号(15位、18位数字):^\d{15}|\d{18}$
短身份证号码(数字、字母x结尾):^([0-9]){7,18}(x|X)?$ 或 ^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$
帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$
强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
日期格式:^\d{4}-\d{1,2}-\d{1,2}
一年的12个月(01~09和1~12):^(0?[1-9]|1[0-2])$
一个月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$
钱的输入格式:
有四种钱的表示形式我们可以接受:”10000.00″ 和 “10,000.00″, 和没有 “分” 的 “10000″ 和 “10,000″:^[1-9][0-9]*$
这表示任意一个不以0开头的数字,但是,这也意味着一个字符”0″不通过,所以我们采用下面的形式:^(0|[1-9][0-9]*)$
一个0或者一个不以0开头的数字.我们还可以允许开头有一个负号:^(0|-?[1-9][0-9]*)$
这表示一个0或者一个可能为负的开头不为0的数字.让用户以0开头好了.把负号的也去掉,因为钱总不能是负的吧.下面我们要加的是说明可能的小数部分:^[0-9]+(.[0-9]+)?$
必须说明的是,小数点后面至少应该有1位数,所以”10.”是不通过的,但是 “10″ 和 “10.2″ 是通过的:^[0-9]+(.[0-9]{2})?$
这样我们规定小数点后面必须有两位,如果你认为太苛刻了,可以这样:^[0-9]+(.[0-9]{1,2})?$
这样就允许用户只写一位小数。下面我们该考虑数字中的逗号了,我们可以这样:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$
1到3个数字,后面跟着任意个 逗号+3个数字,逗号成为可选,而不是必须:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$
备注:这就是最终结果了,别忘了”+”可以用”*”替代。如果你觉得空字符串也可以接受的话(奇怪,为什么?)最后,别忘了在用函数时去掉去掉那个反斜杠,一般的错误都在这里
xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
中文字符的正则表达式:[\u4e00-\u9fa5]
双字节字符:[^\x00-\xff] (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))
空白行的正则表达式:\n\s*\r (可以用来删除空白行)
HTML标记的正则表达式:<(\S*?)[^>]*>.*?</\1>|<.*? /> (网上流传的版本太糟糕,上面这个也仅仅能部分,对于复杂的嵌套标记依旧无能为力)
首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)
腾讯QQ号:[1-9][0-9]{4,} (腾讯QQ号从10000开始)
中国邮政编码:[1-9]\d{5}(?!\d) (中国邮政编码为6位数字)
IP地址:\d+\.\d+\.\d+\.\d+ (提取IP地址时有用)
IP地址:((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)) (由@飞龙三少 提供,感谢共享)
以上就是货真价实,最全面的正则表达式,希望对大家的学习有所帮助,快点收藏。