做百度网站需要多少钱,免费招标平台,网站建设600分站优缺点,网站推广 英文开源中国提供的正则表达式测试工具 http://tool.oschina.net/regex/#xff0c;输入待匹配的文本#xff0c;然后选择常用的正则表达式#xff0c;就可以得出相应的匹配结果了
常用的匹配规则如下
模 式描 述\w匹配字母、数字及下划线\W匹配不是字母、数字及下划线的…开源中国提供的正则表达式测试工具 http://tool.oschina.net/regex/输入待匹配的文本然后选择常用的正则表达式就可以得出相应的匹配结果了
常用的匹配规则如下
模 式描 述\w匹配字母、数字及下划线\W匹配不是字母、数字及下划线的字符\s匹配任意空白字符等价于 [\t\n\r\f]\S匹配任意非空字符\d匹配任意数字等价于 [0-9]\D匹配任意非数字的字符\A匹配字符串开头\Z匹配字符串结尾如果存在换行只匹配到换行前的结束字符串\z匹配字符串结尾如果存在换行同时还会匹配换行符\G匹配最后匹配完成的位置\n匹配一个换行符\t匹配一个制表符^匹配一行字符串的开头$匹配一行字符串的结尾.匹配任意字符除了换行符当 re.DOTALL 标记被指定时则可以匹配包括换行符的任意字符[…]用来表示一组字符单独列出比如 [amk] 匹配 a、m 或 k不在 [] 中的字符比如 匹配除了 a、b、c 之外的字符*匹配 0 个或多个表达式匹配 1 个或多个表达式?匹配 0 个或 1 个前面的正则表达式定义的片段非贪婪方式{n}精确匹配 n 个前面的表达式{n, m}匹配 n 到 m 次由前面正则表达式定义的片段贪婪方式ab( )匹配括号内的表达式也表示一个组
match
match 方法会尝试从字符串的起始位置匹配正则表达式如果匹配就返回匹配成功的结果如果不匹配就返回 None。
例如句子‘Hello 123 4567 World_This is a Regex Demo’接下来我们写一个正则表达式
^Hello\s\d\d\d\s\d{4}\s\w{10}开头的 ^ 是匹配字符串的开头也就是以 Hello 开头然后 \s 匹配空白字符用来匹配目标字符串的空格\d 匹配数字3 个 \d 匹配 123然后再写 1 个 \s 匹配空格后面还有 4567我们其实可以依然用 4 个 \d 来匹配但是这么写比较烦琐所以后面可以跟 {4} 以代表匹配前面的规则 4 次也就是匹配 4 个数字然后后面再紧接 1 个空白字符最后 \w{10} 匹配 10 个字母及下划线。
调用match函数
result re.match(^Hello\s\d\d\d\s\d{4}\s\w{10}, content)
print(result)结果为_sre.SRE_Match object; span(0, 25), match‘Hello 123 4567 World_This’
结果是 SRE_Match 对象这证明成功匹配。
该对象有两个方法group 方法可以输出匹配到的内容结果是 Hello 123 4567 World_This这恰好是正则表达式规则所匹配的内容span 方法可以输出匹配的范围结果是 (0, 25)这就是匹配到的结果字符串在原字符串中的位置范围。
匹配目标
用 match 方法可以得到匹配到的字符串内容如果想从字符串中提取一部分内容。可以使用 () 括号将想提取的子字符串括起来。() 实际上标记了一个子表达式的开始和结束位置被标记的每个子表达式会依次对应每一个分组调用 group 方法传入分组的索引即可获取提取的结果。
仍然是上面的例子Hello 1234567 World_This is a Regex Demo
这里我们想把字符串中的1234567提取出来此时可以将数字部分的正则表达式用 () 括起来然后调用了 group(1) 获取匹配结果。
result re.match(^Hello\s(\d)\sWorld, content)
print(result.group(1))group(1)它与 group() 有所不同后者会输出完整的匹配结果而前者会输出第一个被 () 包围的匹配结果。如果还有包裹的内容依次用group1group2输出。
通用匹配
上面的正则表达式可以简化.点可以匹配任意字符除换行符*代表匹配前面的字符无限次组合在一起就可以匹配任意字符了。
对上式进行改写result re.match(^Hello.Demo$, content)将中间部分直接省略全部用 . 来代替最后加一个结尾字符串就好了。
贪婪与非贪婪
使用上面的通用匹配 .* 时可能有时候匹配到的并不是我们想要的结果。看下面的例子
content Hello 1234567 World_This is a Regex Demo
result re.match(^He.*(\d).*Demo$, content)_sre.SRE_Match object; span(0, 40), matchHello 1234567 World_This is a Regex Demo
7只得到了 7 这个数字。
在贪婪匹配下. 会匹配尽可能多的字符。正则表达式中. 后面是 \d也就是至少一个数字并没有指定具体多少个数字因此.* 就尽可能匹配多的字符这里就把 123456 匹配了给 \d 留下一个可满足条件的数字 7最后得到的内容就只有数字 7 了。
这里只需要使用非贪婪匹配就好了。非贪婪匹配的写法是 .*?多了一个
此时就可以成功获取 1234567 了。非贪婪匹配就是尽可能匹配少的字符。当 .? 匹配到 Hello 后面的空白字符时再往后的字符就是数字了而 \d 恰好可以匹配那么这里 .? 就不再进行匹配交给 \d 去匹配后面的数字。
这里需要注意如果匹配的结果在字符串结尾.*? 就有可能匹配不到任何内容了因为它会匹配尽可能少的字符。
修饰符
正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。
content Hello 1234567 World_This
is a Regex Demoresult re.match(^He.*?(\d).*?Demo$, content)在字符串中加了换行符正则表达式还是一样的用来匹配其中的数字。运行直接报错也就是说正则表达式没有匹配到这个字符串返回结果为 None而我们又调用了 group 方法导致 AttributeError。
匹配的是除换行符之外的任意字符当遇到换行符时.*? 就不能匹配了所以导致匹配失败。这里只需加一个修饰符 re.S即可修正这个错误。
result re.match(^He.*?(\d).*?Demo$, content, re.S)这个 re.S 在网页匹配中经常用到。因为 HTML 节点经常会有换行加上它就可以匹配节点与节点之间的换行了。
修饰符
修饰符描 述re.I使匹配对大小写不敏感re.L做本地化识别locale-aware匹配re.M多行匹配影响 ^ 和 $re.S使.匹配包括换行在内的所有字符re.U根据 Unicode 字符集解析字符。这个标志影响 \w、\W、\b 和 \Bre.X该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解
转义匹配
如果目标字符串里面就包含.要用到转义匹配例如
content (百度) www.baidu.com
result re.match(\(百度 \) www\.baidu\.com, content)当遇到用于正则匹配模式的特殊字符时在前面加反斜线转义一下即可。
search
match 方法是从字符串的开头开始匹配的一旦开头不匹配那么整个匹配就失败了。它更适合用来检测某个字符串是否符合某个正则表达式的规则。
这里就有另外一个方法 search它在匹配时会扫描整个字符串然后返回第一个成功匹配的结果。也就是说正则表达式可以是字符串的一部分在匹配时search 方法会依次扫描字符串直到找到第一个符合规则的字符串然后返回匹配内容如果搜索完了还没有找到就返回 None。
首先这里有一段待匹配的 HTML 文本接下来写几个正则表达式实例来实现相应信息的提取
html div idsongs-list
h2 classtitle 经典老歌 /h2
p classintroduction
经典老歌列表
/p
ul idlist classlist-group
li data-view2 一路上有你 /li
li data-view7
a href/2.mp3 singer任贤齐 沧海一声笑 /a
/li
li data-view4 classactive
a href/3.mp3 singer齐秦 往事随风 /a
/li
li data-view6a href/4.mp3 singerbeyond 光辉岁月 /a/li
li data-view5a href/5.mp3 singer陈慧琳 记事本 /a/li
li data-view5
a href/6.mp3 singer邓丽君 但愿人长久 /a
/li
/ul
/div尝试提取 class 为 active 的 li 节点内部的超链接包含的歌手名和歌名此时需要提取第三个 li 节点下 a 节点的 singer 属性和文本。
此时正则表达式可以以 li 开头然后寻找一个标志符 active中间的部分可以用 .? 来匹配。接下来要提取 singer 这个属性值所以还需要写入 singer(.?)这里需要提取的部分用小括号括起来以便用 group 方法提取出来它的两侧边界是双引号。然后还需要匹配 a 节点的文本其中它的左边界是 gt;右边界是 lt;/a。然后目标内容依然用 (.*?) 来匹配所以最后的正则表达式就变成了
li.*?active.*?singer(.*?)(.*?)/a调用 search 方法它会搜索整个 HTML 文本找到符合正则表达式的第一个内容返回。另外由于代码有换行所以这里第三个参数需要传入 re.S。
findall
如果想要获取匹配正则表达式的所有内容就要借助 findall 方法了。该方法会搜索整个字符串然后返回匹配正则表达式的所有内容。
还是上面的 HTML 文本如果想获取所有 a 节点的超链接、歌手和歌名就可以将 search 方法换成 findall 方法。如果有返回结果的话就是列表类型所以需要遍历一下来依次获取每组内容。
[(/2.mp3, 任贤齐 , 沧海一声笑 ), (/3.mp3, 齐秦 , 往事随风 ), (/4.mp3, beyond, 光辉岁月 ), (/5.mp3, 陈慧琳 , 记事本 ), (/6.mp3, 邓丽君 , 但愿人长久 )]
class list
(/2.mp3, 任贤齐 , 沧海一声笑 )
/2.mp3 任贤齐 沧海一声笑
(/3.mp3, 齐秦 , 往事随风 )
/3.mp3 齐秦 往事随风
(/4.mp3, beyond, 光辉岁月 )
/4.mp3 beyond 光辉岁月
(/5.mp3, 陈慧琳 , 记事本 )
/5.mp3 陈慧琳 记事本
(/6.mp3, 邓丽君 , 但愿人长久 )
/6.mp3 邓丽君 但愿人长久sub
想要把一串文本中的所有数字都去掉如果只用字符串的 replace 方法那就太烦琐了这时可以借助 sub 方法。
content 54aK54yr5oiR54ix5L2g
content re.sub(\d, , content)结果如下
aKyroiRixLg这里只需要给第一个参数传入 \d 来匹配所有的数字第二个参数为替换成的字符串如果去掉该参数的话可以赋值为空。
在上面的 HTML 文本中如果想获取所有 li 节点的歌名直接用正则表达式来提取可能比较烦琐。比如可以写成这样子
results re.findall(li.*?\s*?(a.*?)?(\w)(/a)?\s*?/li, html, re.S)
for result in results:print(result[1])此时借助 sub 方法就比较简单了。可以先用 sub 方法将 a 节点去掉只留下文本然后再利用 findall 提取就好了
html re.sub(a.*?|/a, , html)
print(html)
results re.findall(li.*?(.*?)/li, html, re.S)
for result in results:print(result.strip())去除后html如下
div idsongs-listh2 classtitle 经典老歌 /h2p classintroduction经典老歌列表/pul idlist classlist-groupli data-view2 一路上有你 /lili data-view7沧海一声笑/lili data-view4 classactive往事随风/lili data-view6 光辉岁月 /lili data-view5 记事本 /lili data-view5但愿人长久/li/ul
/divcompile
compile 方法可以将正则字符串编译成正则表达式对象以便在后面的匹配中复用。
content1 2016-12-15 12:00
content2 2016-12-17 12:55
content3 2016-12-22 13:21
pattern re.compile(\d{2}:\d{2})
result1 re.sub(pattern, , content1)
result2 re.sub(pattern, , content2)
result3 re.sub(pattern, , content3)这里有 3 个日期我们想分别将 3 个日期中的时间去掉这时可以借助 sub 方法。compile 还可以传入修饰符例如 re.S 等修饰符。