突然间学不下去别的东西了,看了眼正则表达式还挺好玩的,学习一下
正则表达式,个人理解就是对复杂字符串的一种简单表示,不过非常专业化,因为没学过的人看起来会觉得极其反人类??
0x00. 准备:
利用python自带的re模块学习
其实只用到了两个功能,分别是:
re.complier() :里面输入我们要匹配的正则表达式规则
re.findall():里面输入需要匹配的字符串
import re
rule = re.compile(r'')
test_str = ""
print(rule.findall(test_str))
准备完毕,接下来开始学习和测试结果!
0x01.元字符:
先只了解一些常见的元字符就够了,其他的等需要的时候再找
\b :匹配单词的开始和结束
import re
rule1 = re.compile(r'he')
rule2 = re.compile(r'\bhe\b')
test_str = "he,hello,hell,hey"
print(rule1.findall(test_str))
print(rule2.findall(test_str))
# result
['he', 'he', 'he', 'he']
['he']
上述的代码以及结果可以看出如果不在单词两边加\b,正则表达式就会识别所有包含he的单词(比如hello,she这类),而不是正好找到he这个单词。
. :匹配除了换行以外的其他字符
比如我们要寻找h开头的长度为3的单词:
import re
rule1 = re.compile(r'\bh..\b')
test_str = "hello,hell,his"
print(rule1.findall(test_str))
# result
['his']
\s :匹配任意的空白符,比如空格和TAB等
\d :匹配数字0-9:
import re
rule1 = re.compile(r'\b\d\d\d\b')
test_str = "123,1625,19282,878,999"
print(rule1.findall(test_str))
# result
['123', '878', '999']
\w:匹配字母或数字或下划线或汉字,和\d一样
^ :匹配字符串开始
$ :匹配字符串结束
import re
rule1 = re.compile(r'\d\d\d')
rule2 = re.compile(r'^\d\d\d$')
test_str = "1234"
print(rule1.findall(test_str))
print(rule2.findall(test_str))
# result
['123']
[]
可以看到对于“1234”这个字符串,\d\d\d 匹配的原则是只要这个字符串里面有三个数字即可,而加了开始结束后则表现为整个字符串必须只由三个数字完全构成
\加上正则表达式中有意义的符号则表现为转移符号,这点跟大多数编程语言想通。
0x02.重复:
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
这里的重复都是指对紧挨着的上一个正则元字符的重复:
可以看一下*, +, ? 的区别:
import re
rule1 = re.compile(r'\bsa\d*\b') # 表示sa开头且后面有0-n个数字
rule2 = re.compile(r'\bsa\d+\b') # 表示sa开头且后面至少有一个数字
rule3 = re.compile(r'\bsa\d?\b') # 表示sa开头且后面有0/1个数字
test_str1 = "sa"
test_str2 = "sa11"
print(rule1.findall(test_str1))
print(rule1.findall(test_str2))
print(rule2.findall(test_str1))
print(rule2.findall(test_str2))
print(rule3.findall(test_str1))
print(rule3.findall(test_str1))
# result
['sa']
['sa11']
[]
['sa11']
['sa']
['sa']
{}用法类似不再重复
0x03.字符类:
[ ] : 用于匹配预先没有定义过的字符集,比如说[1,2,3,4,5], [a,e,i,o,u]等这些,然后这个括号就可以当成元字符来进行操作
当然对于也可以指定字符范围,比如说[0-9],
还有[a-z0-9A-Z]这种写法
例如我们要检测一个用户名以字母开头,且长度不超过10,只能包含数字字母下划线:
rule1 = re.compile(r'^[a-zA-Z]\w{0,9}$')
test_str1 = "A9s92" # 合法用户名
test_str2 = "7askk" # 开头不是字母
test_str3 = "a1234567890" # 长度超过10
print(rule1.findall(test_str1))
print(rule1.findall(test_str2))
print(rule1.findall(test_str3))
# result
['A9s92']
[]
[]
0x04.分支:
表达式1|表达式2|...:
把不同的表达式用 | 来分割,只要字符串满足其中任意一条,就匹配,当然是从左到右进行检测。
如果哪个表达式匹配了,则不再继续检测后面的表达式。
0x05.分组:
也就是用来重复多个字符的操作
用( ) 把想要多此重复的多字符括起来
那我们就可以来写一个判断IP地址是否合法的表达式:
显示结果有一点问题还未找到原因而且表达式有点丑:
import re
rule1 = re.compile(r'^(((2[0-4]\d|25[0-5]|1[0-9]{2}|[1-9]\d|\d)\.){3}((2[0-4]\d|25[0-5]|1[0-9]{2}|[1-9]\d|\d)))$')
test_str1 = "192.168.11.74"
test_str2 = "256.191.292.33"
test_str3 = "188.90.888.1"
print(rule1.findall(test_str1))
print(rule1.findall(test_str2))
print(rule1.findall(test_str3))
# result
[('192.168.11.74', '11.', '11', '74', '74')]
[]
[]
0x06.反义
\W | 匹配任意不是字母,数字,下划线,汉字的字符 |
\S | 匹配任意不是空白符的字符 |
\D | 匹配任意非数字的字符 |
\B | 匹配不是单词开头或结束的位置 |
[^x] | 匹配除了x以外的任意字符 |
[^aeiou] | 匹配除了aeiou这几个字母以外的任意字符 |
记忆起来就是元字符小写对应成对应的大写,字符类之前加上^即可,用法上没什么区别。
参考资料:
http://www.runoob.com/regexp/regexp-metachar.html
http://deerchao.net/tutorials/regex/regex.htm