Python 使用正则表达式 - 1

以前需要使用正则表达式时,就从网上搜索一个现成的来用。就这样,虽然早就接触了正则表达式,但没有真正掌握。近日看了《正则表达式必知必会》一书,觉得一下明白了不少,趁热打铁,用Python试验书中的例子并记录下来。

一、正则表达式的用途

正则表达式是文本处理方面的工具/语言,用来完成搜索和替换操作。

二、python 正则表达式包 re

re模块

>>> import re
>>> pattern = re.compile(r"\\")
>>> pattern.match(r"\author")

re的主要方法

这里只列出方法,详细使用请查看文档。本笔记中主要用到search、findall、sub三个。
match(string[, pos[, endpos]])
search(string[, pos[, endpos]])
findall(string[, pos[, endpos]])
fiditer(string[, pos[, endpos]])
split(string, maxsplit=0)
sub(repl, string, count=0)
subn(repl, string, count=0)

MatchObject

执行match、search、finditer匹配成功会返回MatchObject对象,这个对象中包含了一系列的操作方法。
group([group1, …])
groups([default])
groupdict([default])
start([group])
end([group])
span([group])
expand(template)

三、匹配单个字符

1 search 找到第一个即返回,findall返回一个列表。

In [1]: str = '''
   ...: Hello, my name is Bean. Please visit my website at http:
   ...: //www.forta.com/.
   ...: '''

In [2]: import re

In [3]: pattern = r'my'

In [4]: match = re.search(pattern, str)

In [5]: match
Out[5]: <_sre.SRE_Match at 0x7f85aca0c3d8>

In [6]: match.group()
Out[6]: 'my'

In [7]: tuple = re.findall(pattern, str)

In [8]: tuple
Out[8]: ['my', 'my']

In [9]: 

2 元字符在正则表达式中有特殊含义,如.代表单个的字符、字母、数字,如果要匹配其本身需要转义 \.。另外有些字母是转义后变成元字符,有特殊的含义,如\w、\b等。
In [9]: str = '''
   ...: sales1.xls
   ...: order3.xls
   ...: sales2.xls
   ...: sales3.xls
   ...: apac1.xls
   ...: europe2.xls
   ...: na1.xls
   ...: na2.xls
   ...: sa1.xls
   ...: '''

In [10]: pattern = r'.a.\.xls'

In [11]: tuple = re.findall(pattern, str)

In [12]: tuple
Out[12]: ['na1.xls', 'na2.xls', 'sa1.xls']

四、匹配一组字符

1 用中括号定义一个集合,匹配时只匹配集合中的任意一个字母,不在集合中的字母不匹配,如:[ns] 表示匹配n或s,中括号本身是元字符。在本例中ca1就没有匹配上。
In [16]: str = '''
   ....: sales1.xls
   ....: order3.xls
   ....: sales2.xls
   ....: sales3.xls
   ....: apac1.xls
   ....: europe2.xls
   ....: na1.xls
   ....: na2.xls
   ....: sa1.xls
   ....: ca1.xls
   ....: '''

In [17]: pattern = r'[ns]a.\.xls'

In [18]: tuple = re.findall(pattern, str)

In [19]: tuple
Out[19]: ['na1.xls', 'na2.xls', 'sa1.xls']
2.定义一个区间,如[0-9]表示从0到9的数字,[A-Z]表示大写的字母,但注意[Z-A]这样的表示是错误的。
In [20]: str = '''
   ....: <BODY BGCOLOR="#336633" TEXT="#FFFFFF"
   ....: MARGINWIDTH="0" MARGINEIGHT="0"
   ....: TOPMARGIN="0" LEFTMARGIN="0">
   ....: '''

In [21]: pattern = r'#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]'
In [22]: pattern
Out[22]: '#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]'

In [23]: tuple = re.findall(pattern, str)
In [24]: tuple
Out[24]: ['#336633', '#FFFFFF']
In [25]: 
3.在中括号中用^表示取非操作,如[^0-9]表示除数字以外的其它字符。
In [28]: str = '''
   ....: sales1.xls
   ....: order3.xls
   ....: sales2.xls
   ....: sales3.xls
   ....: apac1.xls
   ....: europe2.xls
   ....: sam.xls
   ....: na1.xls
   ....: na2.xls
   ....: sa1.xls
   ....: ca1.xls
   ....: '''

In [29]: pattern = r'[ns]a[^0-9]\.xls'

In [30]: tuple = re.findall(pattern, str)

In [31]: tuple
Out[31]: ['sam.xls']

In [32]: 

五、元字符

1 元字符有特殊含义,如要访问,必须转义如 [,用\[表示。
2 匹配空白字符 
   \b 回退(并删除)一个字符(Backsapce键)
   \f 换页符
   \n 换行符
   \r 回车符
   \t 制表符(Tab键)
   \v 垂直制表符
3 匹配数字(与非数字)
  \d 等价于[0-9]
  \D 等价于[^0-9]
4 匹配字母和数字(与字母和数字)
 \w 等价于[a-zA-Z0-9_]
5 匹配空白字符(与非空白字符)
  \s 等价于[\f\n\r\t\v]
  \S 等价于[^\f\n\r\t\v]

重复匹配

有多少个匹配
匹配一个或多个字符,+ 作为后缀,如a匹配a,a+匹配一个或多个连续出现的a。类似地,[0-9]匹配任意单个数字,[0-9]+将匹配一个或多个连续的数字。
匹配零个或多个字符,*作为后缀。
匹配零个或一个字符,?作为后缀,如下例中https?://[\w./]+ 即可以匹配http和https
In [32]: str='''
   ....: The URL is http://www.forta.com/, to connect
   ....: securely use https://www.forta.com/ instead.
   ....: '''

In [33]: pattern = r'https?://[\w./]+'

In [34]: tuple = re.findall(pattern, str)

In [35]: tuple
Out[35]: ['http://www.forta.com/', 'https://www.forta.com/']

In [36]: 
匹配的重复次数
设置精确的值{n},除了设置精确的值以外,可以设置范围如:{m, n},设置最少多少次{n,}
In [39]: str = '''
   ....: <BODY BGCOLOR="#336633" TEXT="#FFFFFF"
   ....: MARGINWIDTH="0" MARGINEIGHT="0"
   ....: TOPMARGIN="0" LEFTMARGIN="0">
   ....: '''

In [40]: pattern = r'#[0-9A-Fa-f]{6}'

In [41]: tuple = re.findall(pattern, str)

In [42]: tuple
Out[42]: ['#336633', '#FFFFFF']

In [43]: 
防止过度匹配
缺省情况+、*是贪婪模式匹配,即匹配尽可能多的字符。有些情况下,这种方式不是所希望的,在其后加一个?可以取消贪婪模式,即匹配到符合要求的字符串就可以了。实例如下。模式<[Bb]>.*</[Bb]>匹配整个串,只产生一次匹配。模式<[Bb]>.*?</[Bb]>产生了两次匹配。
In [45]: str = '''
   ....: This offer is not availabel to customers
   ....: living in <B>AK</B> and <B>HI</B>.
   ....: '''

In [46]: pattern = r'<[Bb]>.*</[Bb]>'

In [47]: tuple = re.findall(pattern,str)

In [48]: tuple
Out[48]: ['<B>AK</B> and <B>HI</B>']

In [49]: pattern = r'<[Bb]>.*?</[Bb]>'

In [50]: tuple = re.findall(pattern,str)

In [51]: tuple
Out[51]: ['<B>AK</B>', '<B>HI</B>']

七、位置匹配

边界
使用cat作为模式发生了两次匹配,显然不是想要的结果,改为\bcat\b就只匹配cat这个单词,而不会匹配scattered中的cat了。
In [55]: str = '''
   ....: The cat scattered his food all over the room.
   ....: '''

In [56]: pattern = r'cat'

In [57]: tuple = re.findall(pattern,str)

In [58]: tuple
Out[58]: ['cat', 'cat']

In [59]: pattern = r'\bcat\b'

In [60]: tuple = re.findall(pattern,str)

In [61]: tuple
Out[61]: ['cat']
常用的还有用^匹配字符串开头、$匹配字符串结尾。另外在最前面加上(?m)可以用于多行匹配,此时回车换行相当于一个字符串的分隔符。
In [63]: str = '''
   ....: <SCRIPT>
   ....: function doSpellCheck(form,field){
   ....:    // Make sure not empty
   ....:    if(field.value == ''){
   ....:       return false;
   ....:    }
   ....:    // Init
   ....:    var windowName = 'spellWindow';
   ....:    
   ....:    ...
   ....:    // Done
   ....:    return false;
   ....: }
   ....: </SCRIPT>
   ....: '''

In [64]: pattern = r'(?m)^\s*//.*$'

In [65]: tuple = re.findall(pattern, str)

In [66]: tuple
Out[66]: ['   // Make sure not empty', '   // Init', '   // Done']

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值