学爬虫,需要一点正则表达式来匹配url。记录一下。
#----------------------------------------------------------------
#正则表达式
#re模板
#re.search(pattern, string, flags=0)
#re.match(pattern, string, flags=0)
#re.match()检查是否只在字符串的开头匹配而re.search()检查是否在任何地方 (这是默认情况下,Perl 做的) 的字符串匹配
'''
re.match("c", "abcdef") # No match
re.search("c", "abcdef") # Match
'''
#. : 匹配除了换行符外的所有字符
#| : 或
#^ or \A: 脱字符,匹配输入字符串的开始位置
#$ or \Z: 结束位置
#() : 子组
#(?...) : 开头为?的表示正则表达式的扩展语法
#(?:...) : 非捕获组,即该子组匹配的字符串无法从后面获取(re.findall()会用到!!)
#\数字 : 配合子组使用
#re.search(r'(123)\1(456)\2','123123456456') -> 123123456456
#子组索引从1开始,因为零代表八进制
#[] : 字符类--匹配中括号范围内任意一个字符,把特殊字符看作普通字符(除了\, ^, -, ], 要加\转义符)
#--[12345] : 匹配1,2,3,4,5任意一个
#--[a-z] : 匹配从a到z任意一个
#--[^a-z] : 脱字符放在最前面表示取反, 表示除了小写字符
#{} : 大括号前字符的重复次数
#--nba{5} : a重复5次
#--nba{0,10} : a重复0到10次
#? : 前面一个字符匹配0或1次 == {0,1}
#* : 匹配前面字符0或多次 == {0,}
#+ : 匹配前面字符1或多次 == {1,}
#贪婪模式
#默认情况下*, +, ?的匹配模式是贪婪模式(即会尽可能多地匹配符合规则的字符串)
#--*?, +?, ??启用非贪婪模式。
#--对于字符串'1hdmx1tttt', 正则表达式1hdmx1t+会匹配整个字符串,而1hdmx1t+?为'1hdmx1tttt'
#\b : 匹配单词边界,单词被定义为Unidcode的字母数字或下横线字符(除此为单词边界)
#\B : 匹配非单词边界
#\d : 匹配任何数字 == [0-9]
#\D : 非数字 [^\d]
#\w : 单词字符
#\W : 非单词字符
#\s : 空白字符,Unicode包括(\t \n \f \r \v)和其他空白字符, 开启re.ASCII之包括括号内
#\S : 非空白字符
#\w :Unicode包括所有语言的字符和_和数字, 开启re.ASCII只包括[a-zA-Z0-9]
#\W : \w取反
#re.finditer(pattern, string, flags=0) : 将结果返回迭代器,可迭代
#re.findall(pattern, string, flags=0)
#常规用法:所有匹配到的对象以一个列表方式返回(再无子组的情况下)
#若有一个子组:它会自做聪明地只捕获子组中匹配到的字符串!!
#若有多个子组:它会捕获这些子组匹配到的字符串用元组组合返回给我们。如果不想子组内容被捕获,使用(?:...)子组扩展
#匹配对象的方法(search, match返回匹配对象)
#match.group([group1,...]) : 将匹配内容以字符串返回
#参数为提取索引对应子组匹配的字符串,从1开始
#match.start() : 返回匹配开始地址
#match.end() : 结束位置
#match.span() : 匹配范围
#如果你需要重复地使用某个正则表达式,那么你可以先将该正则表达式编译成模式对象。
#我们使用re.compile()方法来编译
'''
p = re.compile(r'[a-z]')
p.findall('aaaa')
结果
['a', 'a', 'a', 'a']
'''
#regex.search(string[,pos[,endpos]])
#regex.match(string[,pos[,endpos]])
#模式对象方法多了字符串的起始位置和终止位置
#上述flag参数为匹配模式:
#re.I(全拼:IGNORECASE): 忽略大小写(括号内是完整写法,下同)
#re.M(全拼:MULTILINE): 多行模式,改变'^'和'$'的行为(参见上图)
#re.S(全拼:DOTALL): 点任意匹配模式,改变'.'的行为
#re.L(全拼:LOCALE): 使预定字符类 \w \W \b \B \s \S 取决于当前区域设定
#re.U(全拼:UNICODE): 使预定字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性
#re.X(全拼:VERBOSE): 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释
#例:ip地址正则表达式
#ip地址结构:n1:n2:n3:n4 (1 <= n1,n2,n3,n4 <= 255)
#((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)
#解析:
#第一阶段: 2[0-4]\d|25[0-5]|[01]?\d\d?(数字部分)
#--将1~255分为了三种情况:
#--1: 2为百位,十位为0-4,个位便可为0-9任意数字
#--2: 2为百位,5为十位,则个位只能为0-5数字
#--3: 0或1开头,那么后两位便可以为0-9任意数字,?(匹配0或1次)的作用便是去除多余的零,否则无法匹配1只能匹配001
#--一定要注意第三种情况必须放在最后,因为三种情况按顺序依此从前往后匹配。
#比如说255应该匹配情况2,但情况3在前,而情况3会匹配为25,所以便直接匹配25结束匹配。
#第二阶段:((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}
#--较好理解,把数字括为子组,再和.号(\.要转义)括为一层子组一起重复3次
#最后阶段: ((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)
#--纯数字,把第一阶段复制即可