正则表达式学习与python中的应用

时间:2022-02-20 08:04:33

 

 

目录:

     一、正则表达式的特殊符号

     二、几种重要的正则表达式

     三、python的re模块应用

     四、参考文献

 

一、正则表达式的特殊符号

特殊符号可以说是正则表达式的关键,掌握并且可以灵活运用重要的python符号,基本就搞定了正则表达式,不过我不敢说自己已经到了炉火纯青的地步。

.(点号),该符号可以匹配任何的字符,当然要换行符除外。在python中,如果存在re.DOTALL,那么即使是换行符,也同样可以匹配,这个DOTALL就是一个标记flag.

eg:re.compile(r'\b\w.’,re.DOTALL)

说明:

1.这个点号和字符串的点不要混淆,如果不用该符号,而用自己编写的正则表达式,想匹配点号,就一定要加个转义符\.

2.正则表达式使用反斜杠" \ "来代表特殊形式或用作转义字符。正则表达式字符和ASCII字符之间有冲突,比如\b表示退格键,但是在正则表达式中表示以某个字符或字符串为边界。要想不发生冲突就要用转义字符,但如果每个正则表达式都用上转义字符,会变得很麻烦,所以原始字符串就应用而生了,它主要是解决该类问题,只需在正则表达式外加上r即可。

^ 表示匹配字符串的开头。如果存在多行字符串,那么可以加上re.M,就可以匹配多行的开头了。^ds

$该符号与上一个正好相反,它匹配的是结尾。

* 表示它左边的正则表达式出现0次或者0次以上。

+表示它左边的正则表达式出现至少一次以上。

?表示它左边的正则表达式出现0次或1次。

管道符号“|”,竖杠相当于 或者,可以不止匹配一个字符串,可以匹配被管道符号分割的多个字符串。

[]匹配方括号内任意一个字符串        b[aeiu]t      可以匹配 bat, bet, bit, but.[0-9] 匹配0-9的任何一个数。

花括号{},花括号里面可以是单个值,也可以是一对值,若是单个值n,就表示匹配n次,若是一对值,就表示匹配次数为一个范围。{m}  {m,n}

\A 只在字符串的开头匹配

\b 表示边界

\bthe匹配以the开始的字符串

the\b匹配以the结尾的字符串

\bthe\b 匹配单词the

\d匹配任何一个数字,相当于[0-9]

\s表示空白字符,就是空格。

\w代表整个字符数字的字符集,相当于A-Z a-z 0-9

\Z 只匹配字符串的结尾。

[^x]匹配除了字母x的字符,[^xty]匹配除了字母xty的字符。

注意:所有的大写都表示相应的不匹配。

()组建组

以上介绍的基本都是单个字符的重复,如果是多个字符就用元祖

比如:(ab)+,匹配一个以上的ab.

它的另外一个作用是记录,可以用re中的group,groups查看。

 分析一种形式,主要为了说明转义字符的用处:

正则表达式:\(?0\d{2,3}[) -]?\d{8}

它一般是用来匹配固定电话的,前面是区号,后面是号码.

我们对它进行详细分析:

1.电话前面的区号一般是除了第一位0,可能有两位010,也可能有3位,0451。所以括号\d{2,3};后面的号码一般都是6位的。\d{8}

2.现在看前面。\(?,前面的\是转义符,因为电话号码可以有两种表示形式((0451)57561101,或者0451-57561101)。因为括号(也是表达式的元字符,所以要匹配它,要加上转义符后面的问号表示出现0次或者1次。

3.[)-],表示匹配),或者连接符-。

 

二、几种重要的正则表达式

 (?......),问号?后面跟着一串字符或者其他神马的,紧跟着问号’?‘后面的第一个字符或者符号决定了该结构struct的含义以及语法。下面就几种就是不同的该形式的扩展。

  1、(?<=xyz) 在一个字符串中,匹配到xyz,然后匹配随后的字符

       eg: r’(?<=xyz)abc,’adxyzabc’,输出就是abc

  2、(?=......)       与上一个正好相反,匹配之前的字符。

  3、(?P<name>.....),匹配相应字符,并将文本保存在名为name的组里。

  4、(?p=name) 对被命名过的组回溯引用,它可以匹配任何之前的某个指定的group匹配的文本 ,但要注意,如果查看要加引号。m.group('name')

(?P<quote>['"]).*?(?P=quote)(from python.org)

  5、(?:.......) 表示非记录分组,这个分组不会被记录下来,即只匹配,并不捕获匹配的文本,也不给此分组分配组号。(我在验证时,groups返回的一个空组)

  6、(?#......)主要是用来提供注释,对正则表达式不产生任何的影响。

  7、(?!xyz)   匹配该位置后面跟的不是xyz的字符

  8、(?<!xyz)匹配该位置前面不是xyz的字符

 

 

 

 

 

三、python的re模块应用

通过调用dir函数,查询re属性,如下是re模块含有的所有属性

['DEBUG', 'DOTALL', 'I', 'IGNORECASE', 'L', 'LOCALE', 'M', 'MULTILINE', 'S', 'Scanner', 'T', 'TEMPLATE', 'U', 'UNICODE', 'VERBOSE', 'X', '_MAXCACHE', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__version__', '_alphanum', '_cache', '_cache_repl', '_compile', '_compile_repl', '_expand', '_pattern_type', '_pickle', '_subx', 'compile', 'copy_reg', 'error', 'escape', 'findall', 'finditer', 'match', 'purge', 'search', 'split', 'sre_compile', 'sre_parse', 'sub', 'subn', 'sys', 'template']

 

compile

预编译正则表达式规则,以便后续使用该正则表达式方便,会返回一个正则对象,regex.

eg:prog = re.compile(pattern) pattern 是你自己定义的正则表达式

search ,match,findall

之所以把他们一起讨论,是因为有相同点,也有不同点。

相同点都是搜索字符根据特定的正则表达式进行匹配;

不同点:

match只是匹配字符串的开头,如果不匹配,就退出,返回一个None。

search可以匹配字符串的任意位置,如果整个字符串都不匹配,返回一个None

findall和search差不多,只不过时它始终返回一个列表,即使不匹配,也要返回一个空列表[],而search和match返回的是元祖。

result = prog.match(string)
print result.group()  group是子元祖,如果显示所有的,就用groups。
result = prog.search(string)
print result.group()
result = prog.findall(string)
print result

split(pattern,string, max=0)        根据正则表达式pattern 中的分隔符把字符string 分割 为一个列表,返回成功匹配的列表,最多分割max 次(默认是分割所有匹配的地方)。 re.split(':','fe:dw:efg')

sub(pattern, repl, string, max=0) 把字符串string 中所有匹配正则表达式pattern 的地方替换成字符串repl,如果max 的值没有给出,则对所有匹配的地方进行替换(另外,请参考subn(),它还会返回一个表示替换次数的数值)。

 

几种特殊标志flags:

  • re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同)
  • M(MULTILINE): 多行模式,改变'^'和'$'的行为(参见上图)
  • S(DOTALL): 点任意匹配模式,改变'.'的行为
  • L(LOCALE): 使预定字符类 \w \W \b \B \s \S 取决于当前区域设定
  • U(UNICODE): 使预定字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性
  • X(VERBOSE): 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释。以下两个正则表达式是等价的:
  • DOTALL,前文中已经讲解。

eg:

a = re.compile(r"""\d +  # the integral part

\.    # the decimal point

\d *  # some fractional digits""", re.X)

b = re.compile(r"\d+\.\d*")

 

下面的是我在cygwin中用vim编写的简单的re模块,已验证。


6 a='800-555-122'
7 b='555-123'
8 p=re.compile(r'(\d{3})?-?(\d{3})-?(\d*)')
9 print p.findall(a)
10
11
12 c=re.search(r'[bh][aiu]t','bit')
13 print c.group()
14 d=re.search(r'\w+,\s\w','Dywane, W')
15 print d.group()
16
17 url=['www.baidu.com','www.sina.cn','www.bjtu.edu.cn']
18 q=re.compile(r'(www.)\w*\.(com|cn|edu)\.?\w*')
19 for i in range(len(url)):
20     try:
21         print url[i]
22         r=q.search(url[i])
23         if r!=None:
24
25             print 'match success',r.group()
26         else:
27             pass
28     except:
29         print 'Error'
30
31 print "15-4,match all python's indicator"
32
33 print re.search(r'\d+','133234').group()
34 print re.search(r'\d+\.?\d*','2').group()
35
36 t=str(type(0))
37 print t
38 w=re.search(r"(?<=type\s\')\w+",t).group()
39 if w==None:
40     pass
41 else:
42     print w
43
44 print re.search(r'[0-9][0-2]?','2').group()


 

 

四、参考文献

【1】 python核心编程第二版

【2】www.python.org的module部分,re模块

【3】Learning  python

【4】python从入门到精通

【5】 python 程序开发指南