正则表达式可用于字符串处理,用于抓取有用信息。在Python中需要引入re模块
import re
正则的三种用法:
1. re.match
尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none
str="Hello World"
pattern="^[\sa-zA-Z]+$"
print(re.match(pattern,str))
结果为:<_sre.SRE_Match object; span=(0, 11), match='Hello World'>
在这里,flag参数种类:
re.I | 使匹配对大小写不敏感 |
re.L | 做本地化识别(locale-aware)匹配 |
re.M | 多行匹配,影响 ^ 和 $ |
re.S | 使 . 匹配包括换行在内的所有字符 |
re.U | 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. |
re.X | 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。 |
2. re.search方法
此方法会逐个检查字符串,并返回第一个匹配成功的字符串
str="Hello World123"
pattern="[0-9]+"
print(re.search(pattern,str).group())
结果为123
match和search一旦匹配成功,就是一个match object对象,而match object对象有以下方法:
- group() 返回被 RE 匹配的字符串
- start() 返回匹配开始的位置
- end() 返回匹配结束的位置
- span() 返回一个元组包含匹配 (开始,结束) 的位置
str="Hello World123"
pattern="([0-9]{2})([0-9]+)"
print(re.search(pattern,str).groups())
结果为('12', '3')
group就是返回了匹配在括号中的字符段。
3. findall()
遍历字符串并返回所有匹配的结果
str="1E 8C 3D7 60 82 A3D FD 25 E8 3E "
pattern="[\w]{3}"
print(re.findall(pattern,str))
结果为:
['3D7', 'A3D']
4. finditer()
finditer()与findall()类似,不同的是:finditer()返回MatchObject类型的迭代器,需要使用类的方法进行访问(如代码中的i.group())。而findall()返回的是字符串list或元祖的list,可以用下标进行访问。
代码来自:https://blog.csdn.net/wali_wang/article/details/50623991
content = '''email:[email protected]
email:[email protected]
email:[email protected]
'''
result_finditer = re.finditer(r"\d+@\w+.com", content)
#由于返回的为MatchObject的iterator,所以我们需要迭代并通过MatchObject的方法输出
for i in result_finditer :
print i.group()
result_findall = re.findall(r"\d+@\w+.com", content)
#返回一个[] 直接输出or或者循环输出
print result_findall
for i in result_findall :
print i
5. split()
str="one1two2three3four4five5"
print(re.split("[0-9]+",str))
结果为['one', 'two', 'three', 'four', 'five', '']
6. sub()
text = "LiMei is a lovely girl, he is beutiful,he is clever, he is also cute"
print(re.sub('he', 'she', text))
结果为:LiMei is a lovely girl, she is beutiful,she is clever, she is also cute
例子:
以下为汽车的CAN信号报文,我们利用正则对其进行信息抓取:
其中第一列为接受时间,第四列为报文ID, RX表示接受,8表示位数, 最后的一部分为十六进制信息
现在对其中一行进行信息提取,例如
text = "0.015018 CAN 1 116 CAN Frame Rx 8 F5 04 26 50 75 51 8E FF"
pattern1="([\.\d]+)[\s]CAN[\d\D]+"
time=re.findall(pattern1,text)[0]#time 截取第一段获取时间
strs=re.split("CAN",text)
id=re.split( "\s",strs[1])[2]
data=re.split("\s" ,strs[2],4)[4]
成功的将有用的信息提取出来。
pattern字符含义:
. |
匹配任意除换行符"\n"外的字符(在DOTALL模式中也能匹配换行符 | a.c |
abc |
\ |
转义字符,使后一个字符改变原来的意思 |
a\.c;a\\c |
a.c;a\c |
* |
匹配前一个字符0或多次 |
abc* |
ab;abccc |
+ |
匹配前一个字符1次或无限次 |
abc+ |
abc;abccc |
? |
匹配一个字符0次或1次 |
abc? |
ab;abc |
^ |
匹配字符串开头。在多行模式中匹配每一行的开头 | ^abc | abc |
$ |
匹配字符串末尾,在多行模式中匹配每一行的末尾 | abc$ | abc |
| | 或。匹配|左右表达式任意一个,从左到右匹配,如果|没有包括在()中,则它的范围是整个正则表达式 | abc|def |
abc def |
{} | {m}匹配前一个字符m次,{m,n}匹配前一个字符m至n次,若省略n,则匹配m至无限次 | ab{1,2}c |
abc abbc |
[] |
字符集。对应的位置可以是字符集中任意字符。字符集中的字符可以逐个列出,也可以给出范围,如[abc]或[a-c]。[^abc]表示取反,即非abc。 所有特殊字符在字符集中都失去其原有的特殊含义。用\反斜杠转义恢复特殊字符的特殊含义。 |
a[bcd]e |
abe ace ade |
() |
被括起来的表达式将作为分组,从表达式左边开始没遇到一个分组的左括号“(”,编号+1. 分组表达式作为一个整体,可以后接数量词。表达式中的|仅在该组中有效。 |
(abc){2} a(123|456)c |
abcabc a456c |
\d |
数字:[0-9] | a\bc |
a1c |
\D |
非数字:[^\d] | a\Dc |
abc |
\s |
匹配任何空白字符:[<空格>\t\r\n\f\v] | a\sc |
a c |
\S | 非空白字符:[^\s] | a\Sc |
abc |
\w |
匹配包括下划线在内的任何字字符:[A-Za-z0-9_] | a\wc |
abc |
\W |
匹配非字母字符,即匹配特殊字符 | a\Wc |
a c |
\A |
仅匹配字符串开头,同^ | \Aabc | abc |
\Z |
仅匹配字符串结尾,同$ | abc\Z |
abc |
\b |
匹配\w和\W之间,即匹配单词边界匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。 | \babc\b a\b!bc |
空格abc空格 a!bc |
\B |
[^\b] | a\Bbc |
abc |