python面试的100题(21)

正则表达式

94.请写出一段代码用正则匹配出ip?

ip地址的生成规则。

  IP地址,是由32位数字二进制转为四个十进制的字符串组成。

  怎么转化?下面讲解:

      二进制:11111111111111111111111111111111

      分为四部分:11111111.11111111.11111111.11111111

      转化:2^7+2^6+2^5+2^4+2^3+2^2+2^1+2^0=255

      转为十进制范围:0~255.0~255.0~255.0~255

      这就是IP地址的范围。

      根据这个生成IP的规则和范围,我们可以用正则表达式来匹配出IP地址,但怎么匹配呢?各人有各人的方法,这里我讲解一下我的思路。

      根据IP地址的字符串规律,我把匹配IP地址的表达式分为两部分来考虑。

      第一部分:匹配3个0~255.(注意后面的一个点)

扫描二维码关注公众号,回复: 5652954 查看本文章

      第二部分:匹配最后的数字0~255

      也就是说,先匹配出 0~255.(注意后面的一个点) 这个字符串,然后重复匹配3次,然后再匹配最后的数字部分0~255。这就是我匹配IP地址的思路。

       首先,我要提一下,正则是没有办法做数字运算的,所以,我们无法用数字运算的方式筛选出IP的数字范围。既然没法用数字运算的方式筛选出IP的数字范围,那么我们应该用什么其他方式来筛选这个数字范围呢?我的思路是分组讨论,然后再把这些分组合并起来组成IP的数字范围。

       ①、假设IP的数字是百位数,那么根据IP的数字范围,我们可以得出下面几种情况。假设第一个数字为1,那么这个数字的范围就为1[0-9][0-9]。这个应该不难理解,就不解释。

      ②、假设第一个数字为2,那么根据IP数字的范围规则,这里又要分为两种情况,为什么?你想想,最大数字是255,当十位数为5时,个位数最大只能为5是吧?而当十位数为0到4时,个位数可以是任意数字对吧?

      所以,这里的两种情况分别为:

           A、2[0-4][0-9]

           B、25[0-5]

       ③、分析完了百位数的情况,接下来就是十位数的情况了,假如是十位数,那么十位数的前面第一个数不能为零是吧?

所以十位数的情况可以是:[1-9][0-9]

       ④、剩下的就是个位数的情况了,个位数的情况,大家应该很容易得出结论,就是:[0-9]。

       四种情况分析下来,我们得出了IP数字的范围分组为:

        1[0-9][0-9]

        2[0-4][0-9]

        25[0-5]

        [1-9][0-9]

        [0-9]

       怎么把上面的分组用正则表达式表示出来呢?很简单,用正则的或符号|和分组符号()就可以了,所以上面的分组正则表达式为:

(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])|([1-9][0-9])|([0-9])

写到这里,数字的匹配范围正则表达式已经写好了,那么根据我前面的思路: 第一部分:匹配3个0~255.(注意后面的一个点)

         第二部分:匹配最后的数字0~255

        我们来匹配IP地址的第一部分,正则表达式如下: 

(1[0-9][0-9]\.)|(2[0-4][0-9]\.)|(25[0-5]\.)|([1-9][0-9]\.)|([0-9]\.)

我在每个数字的后面加了一个点就是匹配出0~255.(注意后面的一个点)

         那么怎么重复匹配三次呢?很简单,我们只要把这五个分组当成整体,再重复匹配三次就行了,正则表达式如下:

((1[0-9][0-9]\.)|(2[0-4][0-9]\.)|(25[0-5]\.)|([1-9][0-9]\.)|([0-9])\.)){3}

第一部分已经匹配出来了,接下来就是拼接上第二部分的数字了,数字部分上面已经写得很清楚了,就不再解释了,下面是完整的正则表达式:

((1[0-9][0-9]\.)|(2[0-4][0-9]\.)|(25[0-5]\.)|([1-9][0-9]\.)|([0-9]\.)){3}((1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])|([1-9][0-9])|([0-9]))

参考地址:https://blog.csdn.net/znzxc/article/details/84061280

96.Python字符串查找和替换?

Python 截取字符串使用 变量[头下标:尾下标],就可以截取相应的字符串,其中下标是从0开始算起,可以是正数或负数,下标可以为空表示取到头或尾。

# 例1:字符串截取
str = '12345678'
print str[0:1]
>> 1            # 输出str位置0开始到位置1以前的字符
print str[1:6]        
>> 23456            # 输出str位置1开始到位置6以前的字符
num = 18
str = '0000' + str(num)    # 合并字符串
print str[-5:]        # 输出字符串右5位
>> 00018            

Python 替换字符串使用 变量.replace("被替换的内容","替换后的内容"[,次数]),替换次数可以为空,即表示替换所有。要注意的是使用replace替换字符串后仅为临时变量,需重新赋值才能保存。

# 例2:字符串替换
str = 'akakak'
str = str.replace('k',' 8')    # 将字符串里的k全部替换为8
print str
>> 'a8a8a8'        # 输出结果

Python 查找字符串使用 变量.find("要查找的内容"[,开始位置,结束位置]),开始位置和结束位置,表示要查找的范围,为空则表示查找所有。查找到后会返回位置,位置从0开始算,如果每找到则返回-1。

# 例3:字符串查找
str = 'a,hello'
print str.find('hello')    # 在字符串str里查找字符串hello
>> 2            # 输出结果

Python 分割字符串使用 变量.split("分割标示符号"[分割次数]),分割次数表示分割最大次数,为空则分割所有。

例4:字符分割
str = 'a,b,c,d'
strlist = str.split(',')    # 用逗号分割str字符串,并保存到列表
for value in strlist:    # 循环输出列表值
    print value
>> a            # 输出结果
>> b
>> c
>> d

参考地址:https://www.cnblogs.com/baoendemao/p/3804664.html

98.正则表达式贪婪与非贪婪模式的区别?

1.什么是正则表达式的贪婪与非贪婪匹配

  如:String str="abcaxc";

    Patter p="ab.*c";

  贪婪匹配:正则表达式一般趋向于最大长度匹配,也就是所谓的贪婪匹配。如上面使用模式p匹配字符串str,结果就是匹配到:abcaxc(ab.*c)。

  非贪婪匹配:就是匹配到结果就好,就少的匹配字符。如上面使用模式p匹配字符串str,结果就是匹配到:abc(ab.*c)。

2.编程中如何区分两种模式

  默认是贪婪模式;在量词后面直接加上一个问号?就是非贪婪模式。

  量词:{m,n}:m到n个

     *:任意多个

     +:一个到多个

     ?:0或一个

参考地址:https://www.cnblogs.com/xudong-bupt/p/3586889.html

99.写出开头匹配字母和下划线,末尾是数字的正则表达式?

1.由数字、26个英文字母或者下划线组成的字符串:
    ^[0-9a-zA-Z_]{1,}$
2.非负整数(正整数 + 0 ):
    ^/d+$
3. 正整数:
    ^[0-9]*[1-9][0-9]*$
4.非正整数(负整数 + 0):
    ^((-/d+)|(0+))$
5. 负整数 :
    ^-[0-9]*[1-9][0-9]*$
6.整数:    
    ^-?/d+$
7.非负浮点数(正浮点数 + 0):
    ^/d+(/./d+)?$
8.正浮点数 :
    ^(([0-9]+/.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*/.[0-9]+)|([0-9]*[1-9][0-9]*))$
9. 非正浮点数(负浮点数 + 0):
    ^((-/d+(/./d+)?)|(0+(/.0+)?))$
10.负浮点数 :
    ^(-(([0-9]+/.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*/.[0-9]+)|([0-9]*[1-9][0-9]*)))$
11. 浮点数 :
    ^(-?/d+)(/./d+)?$
12.由26个英文字母组成的字符串 :    
    ^[A-Za-z]+$
13. 由26个英文字母的大写组成的字符串 :
    ^[A-Z]+$
14.由26个英文字母的小写组成的字符串 :
    ^[a-z]+$
15. 由数字和26个英文字母组成的字符串 :
    ^[A-Za-z0-9]+$
16.由数字、26个英文字母或者下划线组成的字符串 :    
    ^/w+$
17.email地址 :
    ^[/w-]+(/.[/w-]+)*@[/w-]+(/.[/w-]+)+$
18.url:    
    ^[a-zA-z]+://(/w+(-/w+)*)(/.(/w+(-/w+)*))*(/?/S*)?$
19. 年-月-日:
    /^(d{2}|d{4})-((0([1-9]{1}))|(1[1|2]))-(([0-2]([1-9]{1}))|(3[0|1]))$/
20.月/日/年:
    /^((0([1-9]{1}))|(1[1|2]))/(([0-2]([1-9]{1}))|(3[0|1]))/(d{2}|d{4})$/
21.Emil:
    ^([w-.]+)@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.)|(([w-]+.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(]?)$
22. 电话号码:
    (d+-)?(d{4}-?d{7}|d{3}-?d{8}|^d{7,8})(-d+)?
23.IP地址:
    ^(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5])$
24. 匹配中文字符的正则表达式:
    [/u4e00-/u9fa5]
25.匹配双字节字符(包括汉字在内):
    [^/x00-/xff]
26. 匹配空行的正则表达式:
    /n[/s| ]*/r
27.匹配HTML标记的正则表达式:
    /<(.*)>.*<///1>|<(.*) //>/
28.匹配首尾空格的正则表达式:
    (^/s*)|(/s*$)
29.匹配Email地址的正则表达式:
    /w+([-+.]/w+)*@/w+([-.]/w+)*/./w+([-.]/w+)*
30. 匹配网址URL的正则表达式:
    ^[a-zA-z]+://(//w+(-//w+)*)(//.(//w+(-//w+)*))*(//?//S*)?$
31. 匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):
    ^[a-zA-Z][a-zA-Z0-9_]{4,15}$
32. 匹配国内电话号码:
    (/d{3}-|/d{4}-)?(/d{8}|/d{7})?
33.匹配腾讯QQ号:
    ^[1-9]*[1-9][0-9]*$
34. 只能输入数字:
    ^[0-9]*$
35.只能输入n位的数字:
    ^/d{n}$
36.只能输入至少n位的数字:
    ^/d{n,}$
37.只能输入m~n位的数字:
    ^/d{m,n}$
38.只能输入零和非零开头的数字:
    ^(0|[1-9][0-9]*)$
39.只能输入有两位小数的正实数:
    ^[0-9]+(.[0-9]{2})?$
40. 只能输入有1~3位小数的正实数:
    ^[0-9]+(.[0-9]{1,3})?$
41.只能输入非零的正整数:
    ^/+?[1-9][0-9]*$
42. 只能输入非零的负整数:
    ^/-[1-9][0-9]*$
43.只能输入长度为3的字符:
    ^.{3}$
44. 只能输入由26个英文字母组成的字符串:
    ^[A-Za-z]+$
45.只能输入由26个大写英文字母组成的字符串:
    ^[A-Z]+$
46. 只能输入由26个小写英文字母组成的字符串:
    ^[a-z]+$
47.只能输入由数字和26个英文字母组成的字符串:
    ^[A-Za-z0-9]+$
48. 只能输入由数字和26个英文字母或者下划线组成的字符串:
    ^/w+$
49.验证用户密码(正确格式为: 以字母开头,长度在5~17 之间,只能包含字符、数字和下划线)
    ^[a-zA-Z]/w{5,17}$
50.验证是否包含有 ^%&',;=?$/"等字符:
    [^%&',;=?$/x22]+
51.只能输入汉字:
    ^[\u4e00-\u9fa5]{0,}$
52、只含有汉字、数字、字母、下划线不能以下划线开头和结尾
    ^(?!_)(?!.*?_$)[a-zA-Z0-9_\u4e00-\u9fa5]+$
53、只含有汉字、数字、字母、下划线,下划线位置不限
    ^[a-zA-Z0-9_\u4e00-\u9fa5]+$
54、2~4个汉字
    @"^[\u4E00-\u9FA5]{2,4}$

55、

第一位是【1】开头,第二位则则有【3,4,5,7,8】,第三位则是【0-9】,第三位之后则是数字【0-9】。
var reg = /^1[3|4|5|7|8][0-9]{9}$/;
手机号第二位不做限制
var reg = /^1[0-9]{10}$/;

参考地址:https://www.cnblogs.com/J-xiaoyu/p/9619640.html

100.正则表达式操作

四大操作:匹配,切割,替换,获取

103.简述Python里面search和match的区别

match()函数只检测字符串开头位置是否匹配,匹配成功才会返回结果,否则返回None

import re
print(re.match("func", "function"))
# 打印结果 <_sre.SRE_Match object; span=(0, 4), match='func'>

print(re.match("func", "function").span())
# 打印结果  (0, 4)

print(re.match("func1", "function"))
# 打印结果 None

注意:print(re.match("func1", "function").span())会报错,因为取不到span

search()函数会在整个字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。

import re
print(re.search("tion", "function"))
# 打印结果 <_sre.SRE_Match object; span=(4, 8), match='tion'>

print(re.search("tion", "function").span())
# 打印结果  (4, 8)

print(re.search("tion1", "function"))
# 打印结果 None

注意:print(re.search("tion1", "function").span())会报错,因为取不到tion1

re模块下的其他常用方法

import re

print(re.findall("a", "a aa ab ac"))  # 返回所有满足匹配条件的结果,放在列表里
# ['a', 'a', 'a', 'a', 'a']

print(re.split('[ab]', 'abcd'))  # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割
# ['', '', 'cd']

ret = re.sub('\d', 'H', 'eva3egon4yuan4', 1)#将数字替换成'H',参数1表示只替换1个
print(ret) #evaHegon4yuan4

ret = re.subn('\d', 'H', 'eva3egon4yuan4')#将数字替换成'H',返回元组(替换的结果,替换了多少次)
print(ret)

obj = re.compile('\d{3}')  #将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字
ret = obj.search('abc123eeee') #正则表达式对象调用search,参数为待匹配的字符串
print(ret.group())  #结果 : 123

import re
ret = re.finditer('\d', 'ds3sy4784a')   #finditer返回一个存放匹配结果的迭代器
print(ret)  # <callable_iterator object at 0x10195f940>
print(next(ret).group())  #查看第一个结果
print(next(ret).group())  #查看第二个结果
print([i.group() for i in ret])  #查看剩余的左右结果

注意:

1 findall的优先级查询:

import re

ret = re.findall('www.(baidu|jd).com', 'www.jd.com')
print(ret)  # ['jd']     这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可

ret = re.findall('www.(?:baidu|jd).com', 'www.jd.com')
print(ret)  # ['www.jd.com']

2 split的优先级查询

ret=re.split("\d+","eva3egon4yuan")
print(ret) #结果 : ['eva', 'egon', 'yuan']

ret=re.split("(\d+)","eva3egon4yuan")
print(ret) #结果 : ['eva', '3', 'egon', '4', 'yuan']

#在匹配部分加上()之后所切出的结果是不同的,
#没有()的没有保留所匹配的项,但是有()的却能够保留了匹配的项,
#这个在某些需要保留匹配部分的使用过程是非常重要的。

参考地址:https://www.cnblogs.com/aaronthon/p/9435967.html


猜你喜欢

转载自www.cnblogs.com/Fiona-Y/p/10593483.html