元字符
. ^ $ * + ? { } [ ] \ | ( )
方括號與特殊字符
[^]:取反
[$]: 去除了元字符含義
[|]:去除元字符含義
\d [0-9]
\D [^0-9]
\s [ \t\n\r\f\v] 匹配所有空字符
\S [^ \t\n\r\f\v] 匹配所有非空字符
\w [a-zA-Z0-9_] 匹配包括下劃線的文字字符
\W [^a-zA-Z0-9_] 取\w的反
\A 匹配開頭, 與^不同之處在於多行時,^代表每行的開頭,而\A就指字符串開頭
\Z 字符串結尾
\b 單詞邊界
\B \b取反
這些特殊含義字符可以放到方括號中[], [\s,\.] 表示可以是空字符,逗號,點
點代表除換行符以外的字符,re.DOTALL 控制點是不是代表所有字符
元字符含義
* 貪婪模式重複匹配 ,零次或者多次
+ 一次或者多次
? 零次或者一次
{m,n} 至少m次,不超過n次
() 分組
* {0,}
+ {1,}
? {0,1}
模式
? 當該字符緊跟在任何一個其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 後面時,匹配模式是非貪婪的。非貪婪模式儘可能少的匹配所搜索的字符串,而默認的貪婪模式則儘可能多的匹配所搜索的字符串。
(pattern) 匹配pattern 並獲取這一匹配。
(?:pattern) 匹配pattern 但不獲取匹配結果,也就是說這是一個非獲取匹配,不進行存儲供以後使用。
(?=pattern) 正向預查,在任何匹配 pattern 的字符串開始處匹配查找字符串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以後使用。
(?!pattern) 負向預查,與(?=pattern)作用相反
re模塊
通過編譯好的正則表達式對象,可以間接的提高正則表達式的效率
p = re.compile('ab*', re.IGNORECASE)
p = re.compile('ab*')
正則表達式對象,有4個方法
match() 從字符串開頭匹配
search() 掃描整個字符串,看能否找到匹配項
match和search的區別在於:
match從字符串的開始處匹配,而search是從整個字符串來匹配的,
如re.match('foo', 'seafood')將匹配失敗, re.search('foo', 'seafood')則匹配成功
findall() 找到所有的匹配項,並返回一個列表
finditer() 找到所有匹配項,並返回一個iterator
match對象有4個方法
Method/Attribute Purpose
group() 返回匹配的字符串
start() 返回匹配字符串的起始位置
end() 返回匹配字符串的結束位置
span() 返回位置對(起始位置,結束位置)
group(0) 所有匹配,默認選項
group('name') 可以給組指定名字
groups() 返回一個匹配的元組
注:加上re.VERBOSE排除註釋,有了註釋的好處就是方便回頭理解正則表達式代碼
charref = re.compile(r"""
&[#] # Start of a numeric entity reference
(
0[0-7]+ # Octal form
| [0-9]+ # Decimal form
| x[0-9a-fA-F]+ # Hexadecimal form
)
; # Trailing semicolon
""", re.VERBOSE)
修改string的方法
split() 通過匹配項進行分割,分割成list
sub() 找到所有匹配項,並替換
subn() 與sub方法相同,只是返回替換後的字符串和替換的數量
實例
通過match 定位匹配字符串位置
import re
pattern = 'this'
text = 'Does this text match the pattern?'
match = re.search(pattern, text)
s = match.start()
e = match.end()
print 'Found "%s" in "%s" from %d to %d ("%s")' % (match.re.pattern, match.string, s, e, text[s:e])
結果
Found “this” in “Does this text match the pattern?” from 5 to 9 (“this”)
正則表達式對象
# #通過編譯complie方法將一個string變成一個RegexObject即正則表達式對象
# #使用compile不用去看cache,通過compile可以在加載模塊時預編譯語句因此改變了程序的響應時間
regexes = [re.compile(p) for p in ['this', 'that']]
text = 'Does this text match the pattern?'
print 'Text: %r\n' % text
for regex in regexes:
print 'Seeking "%s" ->' % regex.pattern,
#通過search查找文本
if regex.search(text):
print 'match!'
else:
print 'no match
’
結果
Text: ‘Does this text match the pattern?’
Seeking “this” -> match!
Seeking “that” -> no match
findall
# #多個匹配 findall
text = 'abbaaabbbbaaaaa'
pattern = 'ab'
for match in re.findall(pattern, text):
print 'Found "%s"' % match
結果
Found “ab”
Found “ab”
finditer
# #通過finditer返回一個Match實例,而不是findall中返回的是string
for match in re.finditer(pattern, text):
s = match.start()
e = match.end()
print 'Found "%s" at %d:%d' % (text[s:e], s, e)
結果
Found “ab” at 0:2
Found “ab” at 5:7
group
import re
TEST1 = '''
test.com/geo/search.php?lang=zh-Hans&reallogin=0
'''
TEST2 = '''
/geo/search.php?lang=zh-Hans&reallogin=0
'''
TEST3 = '''
https://test.com/geo/search.php?lang=zh-Hans&reallogin=0
'''
URIREX = re.compile('''
(?P<proto> # http,https:// 協議 可以選擇性出現
((http)s?://)?)
(?P<domain> # 域名匹配 如api.jiayuan.com,每個字段長度不超過63,可以選擇性出現
((\w\w{0,61}\w\.)+\w{2,})?)
(?P<uri> # 匹配uri, 如/impressionSearchAndriod.php,必需包含
(/[\w,\.,-]{2,})+)
(?P<param> # 匹配參數 如?lang=zh-Hans&reallogin=0&ver=5.3
(\?\S+=\S+&?)+)
''', re.VERBOSE)
# 輸出每個group的值
for i in xrange(1, 4):
print '-'*50
temp = eval("TEST"+str(i))
print URIREX.search(temp)
if URIREX.search(temp):
p = URIREX.search(temp)
print p.group('proto')
print p.group('domain')
print p.group('uri')
print p.group('param')
結果
————————————————–
<_sre.SRE_Match object at 0x022FA5F8>
test.com
/geo/search.php
?lang=zh-Hans&reallogin=0
————————————————–
<_sre.SRE_Match object at 0x022FA708>
/geo/search.php
?lang=zh-Hans&reallogin=0
————————————————–
<_sre.SRE_Match object at 0x022FA5F8>
https://
test.com
/geo/search.php
?lang=zh-Hans&reallogin=0