把握了 XPath、CSS 选择器,为什么还要学习正则?
正则表达式,用规范正则解析,个别会把 HTML 当做一般文本,用指定格局匹配当相干文本,适宜小片段文本,或者某一串字符(比方电话号码、邮箱账户),或者HTML 蕴含 javascript 的代码,无奈用 CSS 选择器或者 XPath
在线正则表达式测试网站 http://tool.oschina.net/regex…://docs.python.org/zh-cn/3/library/re.html
理解正则表达式
正则表达式是对字符串操作的一种逻辑公式,就是用当时定义好的一些特定字符、及这些特定字符的组合,组成一个 ”规定字符串“,这个 ” 规定字符串 ” 用来表白对字符串的一种过滤逻辑。
正则表达式常见概念
- 边界匹配
^ — 与字符串开始的中央匹配,不匹配任何字符;
$ — 与字符串完结的中央匹配,不匹配任何字符;
str = "cat abdcatdetf ios"
^cat : 验证该行以 c 结尾紧接着是 a,而后是 t
ios$ : 验证该行以 t 结尾倒数第二个字符为 a 倒数第三个字符为 c
^cat$: 以 c 结尾接着是 a ->t 而后是行完结:只有 cat 三个字母的数据行
^$ : 结尾之后马上完结:空白行,不包含任何字符
^ : 行的结尾,能够匹配任何行,因为每个行都有行结尾
b — 匹配一个单词边界,也就是单词和空格之间的地位,不匹配任何字符;
"er\b" 能够匹配 "never" 中的 "er",但不能匹配 "verb" 中的 "er"。
B — b 取非,即匹配一个非单词边界;
"er\B" 能匹配 "verb" 中的 "er",但不能匹配 "never" 中的 "er"。
- 数量词的贪心模式与非贪心模式
正则表达式通常用于在文本中查找匹配的字符串。Python 里数量词默认是贪心的(在多数语言里也可能是默认非贪心),总是尝试匹配尽可能多的字符;非贪心的则相同,总是尝试匹配尽可能少的字符。例如:
正则表达式 "ab*" 如果用于查找 "abbbc",将找到 "abbb"。而如果应用非贪心的数量词 "ab*?",将找到 "a"。
- 反斜杠问题
与大多数编程语言雷同,正则表达式里应用 ”” 作为转义字符,这就可能造成反斜杠困扰。
如果你须要匹配文本中的字符 ””,那么应用编程语言示意的正则表达式里将须要 4 个反斜杠 ”\”:前两个和后两个别离用于在编程语言里本义成反斜杠,转换成两个反斜杠后再在正则表达式里本义成一个反斜杠。
Python 里的原生字符串很好地解决了这个问题,这个例子中的正则表达式能够应用 r ”” 示意。
同样,匹配一个数字的 ”d” 能够写成 r ”d”。有了原生字符串,你再也不必放心是不是漏写了反斜杠,写进去的表达式也更直观。
import re
a=re.search(r"\\","ab123bb\c")
print a.group()
\
a=re.search(r"\d","ab123bb\c")
print a.group()
1
Python Re 模块
Python 自带了 re 模块,它提供了对正则表达式的反对。
match 函数
re.match 尝试从字符串的 起始地位 匹配一个模式,如果不是起始地位匹配胜利的话,match()就返回 none。
上面是此函数的语法:
re.match(pattern, string, flags=0)
这里的参数的阐明:
参数 | 形容 |
---|---|
pattern | 这是正则表达式来进行匹配。 |
string | 这是字符串,这将被搜寻匹配的模式,在字符串的结尾。 |
flags | 标记位,用于管制正则表达式的匹配形式,如:是否辨别大小写,多行匹配等等。 |
匹配胜利 re.match 办法返回一个匹配的对象,否则返回 None。
咱们能够应用 group(num) 或 groups() 匹配对象函数来获取匹配表达式。
匹配对象的办法 | 形容 |
---|---|
group(num=0) | 此办法返回整个匹配(或指定分组 num) |
groups() | 此办法返回所有元组匹配的子组(空,如果没有) |
例子:
import re
line = "Cats are smarter than dogs"
matchObj = re.match(r'(.*) are (.*?) .*', line, re.M|re.I)
if matchObj:
print ("matchObj.group() :", matchObj.group())
print ("matchObj.group(1) :", matchObj.group(1))
print ("matchObj.group(2) :", matchObj.group(2))
else:
print ("No match!!")
当执行下面的代码,它产生以下后果:
matchObj.group() : Cats are smarter than dogs
matchObj.group(1) : Cats
matchObj.group(2) : smarter
正则表达式修饰符 – 选项标记
正则表达式字面能够蕴含一个可选的修饰符来管制匹配的各个方面。修饰符被指定为一个可选的标记。能够应用异或提供多个修饰符(|),如先前所示,并且能够由这些中的一个来示意:
修饰符 | 形容 |
---|---|
re.I<br/>(re.IGNORECASE) | 使匹配对大小写不敏感 |
re.M<br/>(MULTILINE) | 多行匹配,影响 ^ 和 $ |
re.S<br/>(DOTALL) | 使 . 匹配包含换行在内的所有字符 |
re.X<br/>(VERBOSE) | 正则表达式能够是多行,疏忽空白字符,并能够退出正文 |
findall()函数
re.findall(pattern, string, flags=0)
返回字符串中所有模式的非重叠的匹配,作为字符串列表。该字符串扫描左到右,并匹配返回的程序发现
默认:pattren = "\w+"
target = "hello world\nWORLD HELLO"
re.findall(pattren,target)
['hello', 'world', 'WORLD', 'HELLO']
re.I:
re.findall("world", target,re.I)
['world', 'WORLD']
re.S:
re.findall("world.WORLD", target,re.S)
["world\nworld"]
re.findall("hello.*WORLD", target,re.S)
['hello world\nWORLD']
re.M:
re.findall("^WORLD",target,re.M)
["WORLD"]
re.X:
reStr = '''\d{3} #区号
-\d{8}''' #号码
re.findall(reStr,"010-12345678",re.X)
["010-12345678"]
search 函数
re.search 扫描整个字符串并返回第一个胜利的匹配。
上面是此函数语法:
re.search(pattern, string, flags=0)
这里的参数阐明:
参数 | 形容 |
---|---|
pattern | 这是正则表达式来进行匹配。 |
string | 这是字符串,这将被搜寻到的字符串中的任何地位匹配的模式。 |
flags | 标记位,用于管制正则表达式的匹配形式,如:是否辨别大小写,多行匹配等等。 |
匹配胜利 re.search 办法返回一个匹配的对象,否则返回 None。
咱们能够应用 group(num) 或 groups() 匹配对象函数来获取匹配表达式。
匹配对象的办法 | 形容 |
---|---|
group(num=0) | 此办法返回整个匹配(或指定分组 num) |
groups() | 此办法返回所有元组匹配的子组(空,如果没有) |
例子:
import re
line = "Cats are smarter than dogs";
searchObj = re.search(r'(.*) are (.*?) .*', line, re.M|re.I)
if searchObj:
print ("searchObj.group() :", searchObj.group())
print ("searchObj.group(1) :", searchObj.group(1))
print ("searchObj.group(2) :", searchObj.group(2))
else:
print "Nothing found!!"
当执行下面的代码,它产生以下后果:
matchObj.group() : Cats are smarter than dogs
matchObj.group(1) : Cats
matchObj.group(2) : smarter
re.match 与 re.search 的区别
re.match 只匹配字符串的开始,如果字符串开始不合乎正则表达式,则匹配失败,函数返回 None;而 re.search 匹配整个字符串,直到找到一个匹配。
例子:
import re
line = "Cats are smarter than dogs";
matchObj = re.match(r'dogs', line, re.M|re.I)
if matchObj:
print ("match --> matchObj.group() :", matchObj.group())
else:
print ("No match!!")
searchObj = re.search(r'dogs', line, re.M|re.I)
if searchObj:
print ("search --> searchObj.group() :", searchObj.group())
else:
print ("Nothing found!!")
当执行下面的代码,产生以下后果:
No match!!
search --> matchObj.group() : dogs
搜寻和替换
Python 的 re 模块提供了 re.sub 用于替换字符串中的匹配项。
语法
re.sub(pattern, repl, string, max=0)
返回的字符串是在字符串中用 RE 最右边不反复的匹配来替换。
如果模式没有发现,字符将被没有扭转地返回。可选参数 count 是模式匹配后替换的最大次数;count 必须是非负整数。缺省值是 0 示意替换所有的匹配。实例:
例子
上面是一个爬虫做翻页面例子:
import re
url = "http://hr.t encent.com/position.php?&start=10"
page = re.search('start=(\d+)',url).group(1)
nexturl = re.sub(r'start=(\d+)', 'start='+str(int(page)+10), url)
print ("Next Url :", nexturl)
当执行下面的代码,产生以下后果:
Next Url : http://hr.tencent.com/position.php?&start=20
正则表达式语法
下表列出了 Python 中可用正则表达式语法:
在线练习:https://www.520mg.com/it