标签:href 断言 splay arch 标签 png start 常用 none
向我们平常见的那些注册页面啥的,都需要我们输入手机号码,你想我们的电话号码也是有限的吧。(手机号码一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]\d{13,16}[0-9x]$ #^以数字0-9开始, \d{13,16}重复13次到16次 $结束标志 上面的表达式可以匹配一个正确的身份证号码 (2)^[1-9]\d{14}(\d{2}[0-9x])?$ #?重复0次或者1次,当是0次的时候是15位,是1的时候是18位 (3)^([1-9]\d{16}[0-9x]|[1-9]\d{14})$ #表示先匹配[1-9]\d{16}[0-9x]如果没有匹配上就匹配[1-9]\d{14}
举个例子,比如html源码中有<title>xxx</title>标签,用以前的知识,我们只能确定源码中的<title>和</title>是固定不变的。因此,如果想获取页面标题(xxx),充其量只能写一个类似于这样的表达式:<title>.*</title>,而这样写匹配出来的是完整的<title>xxx</title>标签,并不是单纯的页面标题xxx。 想解决以上问题,就要用到断言知识。 在讲断言之前,读者应该先了解分组,这有助于理解断言。 分组在正则中用()表示,根据小菜理解,分组的作用有两个: n 将某些规律看成是一组,然后进行组级别的重复,可以得到意想不到的效果。 n 分组之后,可以通过后向引用简化表达式。 先来看第一个作用,对于IP地址的匹配,简单的可以写为如下形式: \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} 但仔细观察,我们可以发现一定的规律,可以把.\d{1,3}看成一个整体,也就是把他们看成一组,再把这个组重复3次即可。表达式如下: \d{1,3}(.\d{1,3}){3} 这样一看,就比较简洁了。 再来看第二个作用,就拿匹配<title>xxx</title>标签来说,简单的正则可以这样写: <title>.*</title> 可以看出,上边表达式中有两个title,完全一样,其实可以通过分组简写。表达式如下: <(title)>.*</\1> 这个例子实际上就是反向引用的实际应用。对于分组而言,整个表达式永远算作第0组,在本例中,第0组是<(title)>.*</\1>,然后从左到右,依次为分组编号,因此,(title)是第1组。 用\1这种语法,可以引用某组的文本内容,\1当然就是引用第1组的文本内容了,这样一来,就可以简化正则表达式,只写一次title,把它放在组里,然后在后边引用即可。 以此为启发,我们可不可以简化刚刚的IP地址正则表达式呢?原来的表达式为\d{1,3}(.\d{1,3}){3},里边的\d{1,3}重复了两次,如果利用后向引用简化,表达式如下: (\d{1,3})(.\1){3} 简单的解释下,把\d{1,3}放在一组里,表示为(\d{1,3}),它是第1组,(.\1)是第2组,在第2组里通过\1语法,后向引用了第1组的文本内容。 经过实际测试,会发现这样写是错误的,为什么呢? 小菜一直在强调,后向引用,引用的仅仅是文本内容,而不是正则表达式! 也就是说,组中的内容一旦匹配成功,后向引用,引用的就是匹配成功后的内容,引用的是结果,而不是表达式。 因此,(\d{1,3})(.\1){3}这个表达式实际上匹配的是四个数都相同的IP地址,比如:123.123.123.123。 至此,读者已经掌握了传说中的后向引用,就这么简单。 对于分组的理解
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))
标签:href 断言 splay arch 标签 png start 常用 none
原文地址:https://www.cnblogs.com/s686zhou/p/11526779.html