正则表达式

Posted s686zhou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了正则表达式相关的知识,希望对你有一定的参考价值。

向我们平常见的那些注册页面啥的,都需要我们输入手机号码,你想我们的电话号码也是有限的吧。(手机号码一i共11位,并且只以13,14,15,17,18开头的数字这些特点)如果你的输入有误就会提示,那么现实中这个程序的话你觉得用while循环判断简单吗,那么我们看看实现结果

while True:
    phone_number=input(请输入你的电话号码:)
    if len(phone_number)==11 and phone_number.isdigit()        and (phone_number.startswith(13)        or phone_number.startswith(14)         or phone_number.startswith(15)         or phone_number.startswith(17)         or phone_number.startswith(18)):
        print(是合法的手机号码)
    else:
        print(不是合法的手机号码)

看到这个代码,虽说很容易理解,但是还有更简单的方法

import re
phone_number=input(请输入你的电话号码:)
if re.match(^(13|14|15|17|18)[0-9]9$,phone_number):
    ‘‘‘^这个符号表示的是判断是不是以13|14|15|17|18开头的,
    [0-9]: []表示一个字符组,可以表示0-9的任意字符
    9:表示后面的数字重复九次
    $:表示结束符
    ‘‘‘
    print(是合法的手机号码)
else:
    print(不是合法的手机号码)

那么什么是正则呢?

  首先你要知道的是,谈到正则,就只和字符串相关了。在线测试工具http://tool.chinaz.com/regex/

比如你要用‘1’去匹配‘1’,直接就可以匹配上。

字符组

字符组:【字符组】

在同一位置可能出现的各种字符组成了一个字符组,在正则表达式中用【】表示,字符分为很多类,比如数字,字母,标点等等。

假如你现在要求一个位置‘只能出现一个数字’,那么这个位置上的字符只能是0,1,2,3....9

技术图片

 

 

 字符

技术图片

 

 

 量词

技术图片

 

 

 

.^$

技术图片

 

 

 *+?

技术图片

 

 

 注意:前面的*,+,?等都是贪婪匹配,也就是尽可能多的匹配,后面加?就变成了非贪婪匹配,也就是惰性匹配。

贪婪匹配

技术图片

 

 

 几个常用的贪婪匹配

*?;重复任意次,但尽可能少重复
+?:重复一次或更多次,但尽可能少重复
??:重复0次或1次,但尽可能少重复
n,m:重复n到m次,但尽可能少重复
n,: 重复n次以上,但尽可能少重复

 

.*?的用法:

.是任意字符
*是取0到无限长度
?是非贪婪模式
和在一起就是取尽量少的任意字符,一般不会这么单独写,大多用在:
.*?x
意思就是取前面任意长度的字符,直到一个x出现

 

字符集:

技术图片

 

 分组()与或 | 【^】

(1)^[1-9]\\d13,16[0-9x]$     #^以数字0-9开始,
                                \\d13,16重复13次到16次
                                $结束标志
上面的表达式可以匹配一个正确的身份证号码
 
(2)^[1-9]\\d14(\\d2[0-9x])?$     
#?重复0次或者1次,当是0次的时候是15位,是1的时候是18位
 
(3)^([1-9]\\d16[0-9x]|[1-9]\\d14)$
#表示先匹配[1-9]\\d16[0-9x]如果没有匹配上就匹配[1-9]\\d14   
技术图片
举个例子,比如html源码中有<title>xxx</title>标签,用以前的知识,我们只能确定源码中的<title>和</title>是固定不变的。因此,如果想获取页面标题(xxx),充其量只能写一个类似于这样的表达式:<title>.*</title>,而这样写匹配出来的是完整的<title>xxx</title>标签,并不是单纯的页面标题xxx。

       想解决以上问题,就要用到断言知识。

       在讲断言之前,读者应该先了解分组,这有助于理解断言。

       分组在正则中用()表示,根据小菜理解,分组的作用有两个:

 

       n  将某些规律看成是一组,然后进行组级别的重复,可以得到意想不到的效果。

       n  分组之后,可以通过后向引用简化表达式。

 

 

       先来看第一个作用,对于IP地址的匹配,简单的可以写为如下形式:

       \\d1,3.\\d1,3.\\d1,3.\\d1,3

       但仔细观察,我们可以发现一定的规律,可以把.\\d1,3看成一个整体,也就是把他们看成一组,再把这个组重复3次即可。表达式如下:

       \\d1,3(.\\d1,3)3

       这样一看,就比较简洁了。

      

再来看第二个作用,就拿匹配<title>xxx</title>标签来说,简单的正则可以这样写:

       <title>.*</title>

       可以看出,上边表达式中有两个title,完全一样,其实可以通过分组简写。表达式如下:

       <(title)>.*</\\1>

       这个例子实际上就是反向引用的实际应用。对于分组而言,整个表达式永远算作第0组,在本例中,第0组是<(title)>.*</\\1>,然后从左到右,依次为分组编号,因此,(title)是第1组。

       用\\1这种语法,可以引用某组的文本内容,\\1当然就是引用第1组的文本内容了,这样一来,就可以简化正则表达式,只写一次title,把它放在组里,然后在后边引用即可。

       以此为启发,我们可不可以简化刚刚的IP地址正则表达式呢?原来的表达式为\\d1,3(.\\d1,3)3,里边的\\d1,3重复了两次,如果利用后向引用简化,表达式如下:

       (\\d1,3)(.\\1)3

       简单的解释下,把\\d1,3放在一组里,表示为(\\d1,3),它是第1组,(.\\1)是第2组,在第2组里通过\\1语法,后向引用了第1组的文本内容。

       经过实际测试,会发现这样写是错误的,为什么呢?

       小菜一直在强调,后向引用,引用的仅仅是文本内容,而不是正则表达式!

       也就是说,组中的内容一旦匹配成功,后向引用,引用的就是匹配成功后的内容,引用的是结果,而不是表达式。

       因此,(\\d1,3)(.\\1)3这个表达式实际上匹配的是四个数都相同的IP地址,比如:123.123.123.123。

      

       至此,读者已经掌握了传说中的后向引用,就这么简单。

对于分组的理解
对分组的理解

 

分组命名:语法(?p<name>)  注意先命名,后正则

import  re
import re
ret=re.search(<(\\w+)>\\w+<(/\\w+)>,<h1>hello</h1>)   
print(ret.group())
# 给分组起个名字。就用下面的分组命名,上面的方法和下面的分组命名是一样的,只不过就是给命了个名字
ret=re.search(<(?P<tag_name>\\w+)>\\w+</(?P=tag_name)>,<h1>hello</h1>)

#(?P=tag_name)就代表的是(\\w+)  
print(ret.group()) # 了解(和上面的是一样的,是上面方式的那种简写) 
ret=re.search(r<(\\w+)>\\w+</\\1>,<h1>hello</h1>) 
print(ret.group(1))

 

转义符:

技术图片

 

以上是关于正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

PHP 正则表达式总结

正则表达式

正则表达式

正则表达式“或“的使用

正则表达式 验证数字格式 非负数 小数点后保留两位 数字正则 double正则

JS正则表达式详解