----------------初识正则表达式----------------
(1)概念
正则表达式(Regular Expression)是搜索、替换和解析复杂字符串的一种强大而标准的方法。
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,
这个“规则字符串”用来表达对字符串的一种过滤逻辑。
(2)作用
给定一个正则表达式和另一个字符串,我们可以达到如下的目的:
1. 给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”);
2. 可以通过正则表达式,从字符串中获取我们想要的特定部分。
(3)组成元素
正则表达式由一些普通字符和一些元字符组成。
普通字符:大小写字母和数字;
元字符:. ^ $ * + ? {} [] \ | ()
----------------元字符----------------
(1)[]
——[^abc] 字符集合。匹配所包含的任意一个字符。
例如,"[abc]" 可以匹配 "plain" 中的 "a"。
——[^abc] 负值字符集合。匹配未包含的任意字符。
例如,"[^abc]" 可以匹配 "plain" 中的 "plin"。
——[a-z] 字符范围,匹配指定范围内的任意字符。
例如,"[a-z]" 可以匹配 "a" 到 "z" 范围内的任意小写字符。
——[^a-z] 负值字符范围。匹配任何不在指定范围内的任意字符。
例如,"[^a-z]" 可以匹配除了"a" 到 "z" 范围内的任意字符。
注意:元字符在字符集中不起任何元字符的作用 ,作为普通字符对待。
(2).
匹配除换行符外的任意一个字符
(3)^
匹配行首。如果设置了 Multiline属性,^ 也匹配换行字符串中的每个换行。
(4)$
匹配行尾。所谓“行尾”,也就是字符串尾部以及换行符之后的位置。
(5)\
——转义字符,只作用于下一个字符。用于让元字符表现的与普通字符一样的效果。
例如,"\\n" 匹配 \n ;序列"\\" 匹配 "\" 而 "\(" 则匹配 "("。
——反斜杠后面加不同的字符以表示不同特殊意义。
例如,"\n" 匹配换行符;
例如,"\d" 匹配一个数字字符。等价于 [0-9] 。
例如,"\D" 匹配一个非数字字符。等价于 [^0-9] 。
例如,"\s" 匹配任何不可见字符,包括空格、制表符、换页符等等,等价于 [\f\n\r\t\v] 。
例如,"\S" 匹配任何可见字符。等价于 [^\f\n\r\t\v] 。
例如,"\w" 匹配任何字母数字字符。等价于 [a-zA-Z0-9] 。
例如, "\W" 匹配任何非字母数字字符。等价于 [^a-zA-Z0-9] 。
(6)*
——指定前一个字符可以被匹配零次或更多次。匹配引擎会试着重复尽可能多的次数(不超过整数界定的范围,20亿)
例如:"zo*" 可以匹配 "z" ,也能匹配 "zo" 以及 "zoo" 。
—— * 等价于 {0,}
(7)+
——指定前一个字符可以被匹配一次或更多次。
例如:"zo+" 可以匹配 "zo" 以及 "zoo",但不能匹配 "z" 。
—— + 等价于 {1,}
(8)?
——被匹配零次或一次。
例如,"zone?" 可以匹配 "zon" 以及 "zone" 。
——当该字符跟在任何一个其他限制符后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,
而默认的贪婪模式尽可能多的匹配所搜索的字符串。
例如,对于字符串 "ooooo" , "o+?" 将匹配单个 "o" ,而 "o+" 将匹配所有 "o" 。
(9){n}、{n,}、{n,m}
——{n} n是一个非负整数,指定前一个字符可以被匹配n次。
例如,"o{2}" 不能匹配 "Bob" 中的 "o" ,但是能匹配 "food" 中的两个o。
——{n,} n是一个非负整数,指定前一个字符字少匹配 n 次。
例如,"o{2,}" 不能匹配 "Bob" 中的 "o" ,但是能匹配 "foooooood" 中的所有o。 "o{1,}" 等价于 "o+" ;"o{0,}" 等价于 "o*" 。
——{n,m} m 和 n 均为非负整数,其中 n≤m 。最少匹配 n 次且最多匹配 m 次。
例如,"o{1,3}" 将匹配 "foooooood" 中的前三个o。o{0,1}" 等价于 "o?" 。
注意:在逗号和两个数之间不能有空格!
(1)在Python中使用正则表达式时,首先导入模块re。
即 >>>import re
(2)字符串前面加 "r" :禁止转义!反斜杠不会被任何特殊方式处理。
例:
(3)re.findall(pattern,string) ——> list
列出字符串中模式的所有匹配项,并作为一个列表返回。如果无匹配,则返回空列表。
例:
(4)re.compile(pattern,flags=0) ——> pattern object.
根据包含正则表达式的字符串创建模式对象,可以实现更有效率地匹配。
此外,re.cpmpile() 可以通过接受可选的属性,常用来实现不同的特殊功能和语法变更。
例1:
例2:
(5)re.match(pattern, string, flags=0) ——> match object or None
在字符串的开始位置匹配正则。如果无匹配,则返回 None 。
例:
(6)re.search(pattern, string, flags=0) ——> match object or None
在字符串中匹配正则。如果无匹配,则返回 None 。
例5:
(7)MatchObject 方法
——group(): 返回被正则匹配的字符串;
——start(): 返回匹配开始的位置;
——end(): 返回匹配结束的位置;
——span(): 返回一个元组包含匹配(开始,结束)的位置。
(8)re.finditer(pattern,string,flags=0) ——> iterator
列出字符串中模式的所有匹配项,并作为一个迭代器返回。
例:
(9)re.sub(pattern, repl, string, count=0, flags=0) ——> string
将字符串中所有 pattern 的匹配项用 repl 替换。
例:
(10)re.subn(pattern, repl, string, count=0, flags=0) ——> 2-tuple containing new_string and number
与sub()实现相同的替换作用,但是subn()返回一个元组,其中包含新字符串和替换次数。
例:
(11)re.split(pattern, string, maxsplit=0, flags=0) ——> list
根据模式的匹配项来分割字符串。
例:
----------------常用的re的属性----------------
(1)re.I re.IGNORECASE
让正则表达式忽略大小写。此特性和locale无关。
(2)re.L re.LOCALE
做本地化识别,让\w、\W、\b、\B、\s和\S依赖当前的locale。
(3)re.M re.MULTILINE
多行匹配,影响'^'和'$'的行为,指定了以后,'^'会增加匹配每行的开始(也就是换行符后的位置);'$'会增加匹配每行的结束(也就是换行符前的位置)。
(4)re.S re.DOTALL
影响'.'的行为,平时'.'匹配除换行符以外的所有字符,指定了本标志以后,也可以匹配换行符。
(5)re.U re.UNICODE
让\w、\W、\b、\B、\d、\D、\s和\S依赖Unicode库。
(6)re.X re.VERBOSE
运用这个标志,你可以写出可读性更好的正则表达式:除了在方括号内的和被反斜杠转义的以外的所有空白字符,都将被忽略,
而且每行中,一个正常的井号后的所有字符也被忽略,这样就可以方便地在正则表达式内部写注释了。
----------------正则表达式分组----------------
例1:
例2:
----------------利用正则表达式写计算器----------------
----------------利用正则表达式写爬虫----------------
(1)例:
(1)概念
正则表达式(Regular Expression)是搜索、替换和解析复杂字符串的一种强大而标准的方法。
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,
这个“规则字符串”用来表达对字符串的一种过滤逻辑。
(2)作用
给定一个正则表达式和另一个字符串,我们可以达到如下的目的:
1. 给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”);
2. 可以通过正则表达式,从字符串中获取我们想要的特定部分。
由于正则表达式主要应用对象是文本,因此它在各种文本编辑器场合都有应用,小到著名编辑器 EditPlus,大到 Microsoft Word、
Visual Studio 等大型编辑器,都可以使用正则表达式处理文本内容。
(3)组成元素
正则表达式由一些普通字符和一些元字符组成。
普通字符:大小写字母和数字;
元字符:. ^ $ * + ? {} [] \ | ()
----------------元字符----------------
(1)[]
——[^abc] 字符集合。匹配所包含的任意一个字符。
例如,"[abc]" 可以匹配 "plain" 中的 "a"。
——[^abc] 负值字符集合。匹配未包含的任意字符。
例如,"[^abc]" 可以匹配 "plain" 中的 "plin"。
——[a-z] 字符范围,匹配指定范围内的任意字符。
例如,"[a-z]" 可以匹配 "a" 到 "z" 范围内的任意小写字符。
——[^a-z] 负值字符范围。匹配任何不在指定范围内的任意字符。
例如,"[^a-z]" 可以匹配除了"a" 到 "z" 范围内的任意字符。
注意:元字符在字符集中不起任何元字符的作用 ,作为普通字符对待。
(2).
匹配除换行符外的任意一个字符
(3)^
匹配行首。如果设置了 Multiline属性,^ 也匹配换行字符串中的每个换行。
(4)$
匹配行尾。所谓“行尾”,也就是字符串尾部以及换行符之后的位置。
(5)\
——转义字符,只作用于下一个字符。用于让元字符表现的与普通字符一样的效果。
例如,"\\n" 匹配 \n ;序列"\\" 匹配 "\" 而 "\(" 则匹配 "("。
——反斜杠后面加不同的字符以表示不同特殊意义。
例如,"\n" 匹配换行符;
例如,"\d" 匹配一个数字字符。等价于 [0-9] 。
例如,"\D" 匹配一个非数字字符。等价于 [^0-9] 。
例如,"\s" 匹配任何不可见字符,包括空格、制表符、换页符等等,等价于 [\f\n\r\t\v] 。
例如,"\S" 匹配任何可见字符。等价于 [^\f\n\r\t\v] 。
例如,"\w" 匹配任何字母数字字符。等价于 [a-zA-Z0-9] 。
例如, "\W" 匹配任何非字母数字字符。等价于 [^a-zA-Z0-9] 。
(6)*
——指定前一个字符可以被匹配零次或更多次。匹配引擎会试着重复尽可能多的次数(不超过整数界定的范围,20亿)
例如:"zo*" 可以匹配 "z" ,也能匹配 "zo" 以及 "zoo" 。
—— * 等价于 {0,}
(7)+
——指定前一个字符可以被匹配一次或更多次。
例如:"zo+" 可以匹配 "zo" 以及 "zoo",但不能匹配 "z" 。
—— + 等价于 {1,}
(8)?
——被匹配零次或一次。
例如,"zone?" 可以匹配 "zon" 以及 "zone" 。
——当该字符跟在任何一个其他限制符后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,
而默认的贪婪模式尽可能多的匹配所搜索的字符串。
例如,对于字符串 "ooooo" , "o+?" 将匹配单个 "o" ,而 "o+" 将匹配所有 "o" 。
(9){n}、{n,}、{n,m}
——{n} n是一个非负整数,指定前一个字符可以被匹配n次。
例如,"o{2}" 不能匹配 "Bob" 中的 "o" ,但是能匹配 "food" 中的两个o。
——{n,} n是一个非负整数,指定前一个字符字少匹配 n 次。
例如,"o{2,}" 不能匹配 "Bob" 中的 "o" ,但是能匹配 "foooooood" 中的所有o。 "o{1,}" 等价于 "o+" ;"o{0,}" 等价于 "o*" 。
——{n,m} m 和 n 均为非负整数,其中 n≤m 。最少匹配 n 次且最多匹配 m 次。
例如,"o{1,3}" 将匹配 "foooooood" 中的前三个o。o{0,1}" 等价于 "o?" 。
注意:在逗号和两个数之间不能有空格!
(1)在Python中使用正则表达式时,首先导入模块re。
即 >>>import re
(2)字符串前面加 "r" :禁止转义!反斜杠不会被任何特殊方式处理。
例:
>>> print("abc\n")
abc
>>> print("abc\\n")
abc\n
>>> print(r"abc\n")
abc\n
>>> print(r"abc\\n")
abc\\n
(3)re.findall(pattern,string) ——> list
列出字符串中模式的所有匹配项,并作为一个列表返回。如果无匹配,则返回空列表。
例:
>>> import re
>>> s=r"abc"
>>> re.findall(s,"aabbccabdabcaabc")
['abc', 'abc']
(4)re.compile(pattern,flags=0) ——> pattern object.
根据包含正则表达式的字符串创建模式对象,可以实现更有效率地匹配。
此外,re.cpmpile() 可以通过接受可选的属性,常用来实现不同的特殊功能和语法变更。
例1:
>>> import re
>>> s = r"^010-?\d{8}$" # 定义电话号码的正则
>>> re.findall(s,"010-63074291")
['010-63074291']
>>> P_tel = re.compile(s)
>>> P_tel
<_sre.SRE_Pattern object at 0x0000000004130290>
>>> P_tel.findall("010-63074291") # 经过compile转换的正则表达式对象也能用于普通的re函数
['010-63074291']
例2:
>>> import re
>>> s = r"hello"
>>> greeting = re.compile(s,re.I) # re.I 属性让正则表达式忽略大小写!
>>> greeting.findall("HELLO")
['HELLO']
>>> greeting.findall("hello")
['hello']
>>> greeting.findall("Hello")
['Hello']
(5)re.match(pattern, string, flags=0) ——> match object or None
在字符串的开始位置匹配正则。如果无匹配,则返回 None 。
例:
>>> import re
>>> s = r"abc"
>>> S = re.compile(s)
>>> S.match("abcdef") # 在字符串 "abcdef" 开始位置匹配 "abc"
<_sre.SRE_Match object at 0x00000000041C1440>
>>> S.match("hhhhhabc")
>>> print(S.match("hhhhhabc"))
None
(6)re.search(pattern, string, flags=0) ——> match object or None
在字符串中匹配正则。如果无匹配,则返回 None 。
例5:
>>> import re
>>> s = r"abc"
>>> S = re.compile(s)
>>> S.search("abcdef")
<_sre.SRE_Match object at 0x00000000041C1440>
>>> S.search("hhhhhabc")
<_sre.SRE_Match object at 0x00000000041C1440>
(7)MatchObject 方法
——group(): 返回被正则匹配的字符串;
——start(): 返回匹配开始的位置;
——end(): 返回匹配结束的位置;
——span(): 返回一个元组包含匹配(开始,结束)的位置。
(8)re.finditer(pattern,string,flags=0) ——> iterator
列出字符串中模式的所有匹配项,并作为一个迭代器返回。
例:
>>> import re
>>> s = r"abc"
>>> S = re.compile(s)
>>> S.finditer("ancdabsabchqw")
<callable_iterator object at 0x038EAA10>
>>> it = S.finditer("ancdabsabchqw")
>>> for i in it:
print(i.group())
abc
(9)re.sub(pattern, repl, string, count=0, flags=0) ——> string
将字符串中所有 pattern 的匹配项用 repl 替换。
例:
>>> import re
>>> s = r"c..t"
>>> re.sub(s,"python","cvt ccct caat cet")
'cvt python python cet'
>>>
>>> s = r"a.b"
>>> re.sub(s,"hello","adb aab")
'hello hello'
(10)re.subn(pattern, repl, string, count=0, flags=0) ——> 2-tuple containing new_string and number
与sub()实现相同的替换作用,但是subn()返回一个元组,其中包含新字符串和替换次数。
例:
>>> import re
>>> s = r"c..t"
>>> re.sub(s,"python","cvt ccct caat cet")
'cvt python python cet'
>>> re.subn(s,"python","cvt ccct caat cet")
('cvt python python cet', 2)
(11)re.split(pattern, string, maxsplit=0, flags=0) ——> list
根据模式的匹配项来分割字符串。
例:
>>> import re
>>> s = "abc.cdf+ghi*jk"
>>> re.split(r"[\.\+\*]",s)
['abc', 'cdf', 'ghi', 'jk']
----------------常用的re的属性----------------
(1)re.I re.IGNORECASE
让正则表达式忽略大小写。此特性和locale无关。
(2)re.L re.LOCALE
做本地化识别,让\w、\W、\b、\B、\s和\S依赖当前的locale。
(3)re.M re.MULTILINE
多行匹配,影响'^'和'$'的行为,指定了以后,'^'会增加匹配每行的开始(也就是换行符后的位置);'$'会增加匹配每行的结束(也就是换行符前的位置)。
(4)re.S re.DOTALL
影响'.'的行为,平时'.'匹配除换行符以外的所有字符,指定了本标志以后,也可以匹配换行符。
(5)re.U re.UNICODE
让\w、\W、\b、\B、\d、\D、\s和\S依赖Unicode库。
(6)re.X re.VERBOSE
运用这个标志,你可以写出可读性更好的正则表达式:除了在方括号内的和被反斜杠转义的以外的所有空白字符,都将被忽略,
而且每行中,一个正常的井号后的所有字符也被忽略,这样就可以方便地在正则表达式内部写注释了。
----------------正则表达式分组----------------
例1:
>>> email = r"\w{3}@\w+(\.com|\.cn)"#对.com与.cn取或
>>> re.match(email, 'zzz@csvt.com')
<_sre.SRE_Match object at 0x0000000003E64378>
>>> re.match(email, 'zzz@csvt.cn')
<_sre.SRE_Match object at 0x0000000003E643F0>#返回为匹配
>>> re.match(email, 'zzz@csvt.org')#不匹配,返回NONE
>>>
>>> re.findall(email, 'zzz@csvt.com')
['.com']#当有分组时,findall优先只返回分组中匹配的数据
例2:
>>>print s
hhsdf ojd hello src=dsft yes hdf
dasj src=123 yes jdos
src=123 yes
hello src=python yes jkdfh
>>>r1 = r"hello src=.+ yes"
>>>re.findall(r1, s)
['hello src=csvt yes', 'hello src=python yes']#找到 hello ... yes这样的特殊字符串
>>>r1 = r"hello src=(.+) yes"
['csvt', 'python'] #得到src=csvt中csvt的值
----------------利用正则表达式写计算器----------------
import re
s=raw_input()
t=re.findall(r"(\d+\.?\d*)([\+\-\*\/])(\d+\.?\d*)(=)",s)[0]
l=[]
for i in t:
l.append(i)
l[0]=int(l[0])
l[2]=int(l[2])
s={'+':lambda x,y:x+y,'-':lambda x,y:x-y,'*':lambda x,y:x*y,'/':lambda x,y:x/y}
print s[l[1]](l[0],l[2])
----------------利用正则表达式写爬虫----------------
(1)例:
import re
import urllib
def getHtml(url):
page=urllib.urlopen(url)
html=page.read()
return html
def getImg(html):
reg=r'src="(.*?\.jpg)"'
imgre=re.compile(reg)
imglist=re.findall(imgre,html)
x=0
for imgurl in imglist:
imgurl=imgurl.replace("//","http://")
urllib.urlretrieve(imgurl,'%d.jpg'%x)
x+=1
html=getHtml('http://www.80s.tw/')
getImg(html)
(2)网页编码的修改
import sys
type = sys.getfilesystemencoding()
#utf-8为网页编码,可能为gbk等
print html.decode('utf-8').encode(type)
编码声明:
# -*- coding:mbcs -*-