python中提供了re这个模块提供对正则表达式的支持。python
1、正则表达式经常使用到的一些语法(并不是所有):正则表达式
. | 匹配任意单个字符 |
[...] | 匹配单个字符集 |
\w | 匹配单词字符,即[a-zA-Z0-9] |
\W | 匹配非单词字符集,例如 ‘*’ |
\d | 匹配数字,即[0-9] |
\D | 匹配非数字 |
\s | 匹配空白字符 |
\S | 匹配非空白字符 |
* | 匹配前一个字符0次或者任意屡次 |
+ | 匹配前一个字符1次或者任意屡次 |
? | 匹配前一个字符0次或者1次 |
{m} | 匹配前一个字符m次 |
{m,n} | 匹配前一个字符最少m次,最多n次 |
*? | 非贪婪模式匹配前一个字符0次或者任意屡次 |
+? | 非贪婪模式匹配前一个字符1次或者任意屡次 |
?? | 非贪婪模式匹配前一个字符0次或者1次 |
{m,n}? | 非贪婪模式匹配前一个字符最少m次,最多n次 |
^ | 匹配字符串开头 |
$ | 匹配字符串结尾 |
\A | 制定的字符串匹配必须出如今开头 |
\Z | 制定的字符串匹配必须出如今结尾 |
| | 匹配左右任意一个表达式,至关于“或”的含义 |
() | 匹配一个分组,括号中为该分组所需匹配的内容 |
\<number> | 引用匹配编号为<number>的分组中的字符串 |
(?P<group_name>) | 为匹配分组制定特定的组名 |
(?P=<group_name>) | 引用特定组名的匹配字符串 |
几点解释:函数
1. 两种方式均可以进行匹配:学习
(1)首先建立pattern,而后进行matchspa
1 pa = re.compile(r'[\w]{6}') # 首先利用re模块建立一个pattern实例pa 2 ma = pa.match('string') # 利用这一pattern对正则表达式进行匹配 3 ma.group() #打印匹配的内容,输出为'string'
(2)直接利用re模块中的函数match进行匹配code
1 ma = re.match(r'[\w]{6}', ‘string’) 2 print(ma.group()) # 打印匹配的内容,输出为'string'
2. 贪婪模式和非贪婪模式:对象
贪婪模式:老是尝试匹配尽量多的字符;blog
非贪婪模式:老是尝试匹配尽量少的字符。字符串
例如:利用正则表达式‘python*’匹配‘pythonnnnnpython’,此时ma = re.match(r'python*',‘pythonnnpython’),获得的ma.group()为‘pythonnn’;利用‘python*?’进行匹配,此时ma = re.match(r'python*?',‘pythonnnpython’),获得的ma.group()为‘python’。博客
3. 关于逻辑与分组语法的用法:
| | 匹配左右任意一个表达式,至关于“或”的含义 |
() | 匹配一个分组,括号中为该分组所需匹配的内容 |
\<number> | 引用匹配编号为<number>的分组中的字符串 |
(?P<group_name>) | 为匹配分组制定特定的组名 |
(?P=<group_name>) | 引用特定组名的匹配字符串 |
首先,|和()的用法比较容易理解,例如咱们须要匹配多个邮箱的地址是否合法,例若有gmail邮箱、outlook邮箱,假定@前的字符数为6到20个,此时能够写成:
>>> pa = re.compile('[\w]{6,20}@(gmail|outlook).com$')
>>> ma = pa.match('bokeyuan@gmail.com')
>>> ma.group()
'bokeyuan@gmail.com'
>>> ma = pa.match('bokeyuan@outlook.com')
>>> ma.group()
'bokeyuan@outlookl.com'
后边三个的用法根据下边的例子进行说明:
>>> str = '<code>python</code>' >>> ma = re.match(r'<[\w]+>', str) >>> ma.group() '<code>' >>> ma = re.match(r'<([\w]+>)[\w]+</\1', str) >>> ma.group() '<code>python</code>' >>> ma = re.match(r'<(?P<group1>[\w]+>)[\w]+</(?P=group1)', str) >>> ma.group() '<code>python</code>'
其中,第一个例子就是对字符串‘<code>'进行匹配。咱们发现str中其实有两部分是彻底相同的,就是都含有'code>'这个substring,因而能够看第二个例子,咱们用()将([\w]+>)这部份内容括住时,这部分匹配的字符串就是'code>',([\w]+>)就是一个分组,没有起名字的状况下默认<number>为1,所以在咱们须要在末尾再次引用到它的时候,就写上 /1 便可。第三个例子与第二个例子的效果彻底相同,只不过为了更加清楚的记住匹配分组的名字,咱们利用(?P<group_name>)这一语法功能,人为的为这个分组取了一个group1的名字,在最后又引用了这一分组。
4. 注意字符串中转义字符的问题
上述例子中,出如今正则表达式前边的r是原始字符串操做符,能够写为r或者R:表示字符串内的全部字符都按原始意思解释。
例如:‘c:\python\test.py’ 若是不加r,则计算机会将 \t 会变成转义字符解释;加上r之后,写为:r‘c:\python\test.py’,计算机就会直接输出c:\python\test.py,不然要想输出c:\python\test.py,必须将字符串写为‘c:\\python\\test.py’
2、介绍几个re模块中的经常使用函数
1. search(pattern, string, flags=0)函数
search函数功能:在字符串中查找匹配
例如:博客会记录来访者的数量,咱们经过正则匹配查找字符串中的数字:
1 str1 = 'number of visitors = 1000' 2 info = re.search(r'\d+', str1) # 匹配字符串str1中的数字 3 print('访客数量:', info) 4 print(info.group()) # 显示匹配的内容
固然,上述操做也能够经过对字符串直接操做得到,例如:print('访客数量:', str1.find('1000')) 。可是这样存在一个问题,由于访客数量实在不断变化的,一旦1000这个数字增长,用字符串操做就难以实现。可是利用search函数就不存在这样的问题。
2. findall(pattern, string, flags=0)函数
findall函数功能:找到匹配,并返回全部匹配内容的列表
例如,博客记录了最近三天天天的访客记录,咱们须要将三天的访客数量都查找出来,并计算总的访客数量,此时用search函数没法直接将三天的访客数量同时提取,能够采用findall函数:
1 str2 = 'day1=22, day2=34, day3=13' 2 info = re.findall(r'=[\d]+', str2) 3 print(info) 4 print('三天的访客数量为:', sum([int(x[1:]) for x in info]))
3. sub(pattern, repl, string, count=0, flags=0)函数
sub函数功能:将字符串中匹配正则表达式的部分替换为其余值。其中repl能够是一个字符串,也能够是一个函数。
当repl是一个字符串时,仍然以访客记录为例,当增长一个访客时,须要修改记录中的数字:
1 str3 = 'number of visitors = 1000' 2 info = re.sub(r'[\d]+', '1001', str3) 3 print(info) # 此时输出结果为 number of visitors = 1001
可是此时每次修改都必须手动输入数字,显然,对于这种随时变化的数字来讲,这种操做是不合理的。而sub函数的高明之处就是容许repl是一个函数。
当repl为一个函数时,首先会在string中查找pattern的匹配,查找到的匹配是一个match对象,这个match对象就会被传递到repl这个函数中。上述例子能够这样实现:
1 # 首先,定义一个增长访客数量的函数,函数的参数是一个match对象 2 def add_num(match): 3 val = match.group() 4 num = int(val) + 1 5 return str(num) 6 7 str3 = 'number of visitors = 1000' 8 print('最新访客数量:', re.sub(r'[\d]+', add_num, str3)) # 打印结果,最新访客数量:number of visitors = 1001
4. split(pattern, string, maxsplit=0, flags=0)函数
split函数功能:根据匹配分割字符串,返回分割字符串组成的列表
1 str4 = 'day1=22, day2=34, day3=13' 2 print(re.split(r', ', str4)) # 打印出的内容为 ['day1=22', 'day2=34', 'day3=13']
以上就是正则表达式的一些学习笔记,并不十分彻底,欢迎你们交流。