正则表达式中的一些tips[慢慢积累]


正则表达式中的一些坑
0.字符组

在Python中使用的是中括号“[]”,其中的元素组成需要是单个的“字符”,就算是用“()”括起来的,也无法表示单个的字符,很容易出错!

测试数据:

"nt":"3gnet"
"nt":"2g/3g"
"nt":"cmnet"
"nt":"cmwap"
"nt":"ctnet"
"nt":"ctwap"

正则表达式:

regex_net = re.compile(r'(3gnet)|(2g/3g)|(c(m|t)(net|wap))', re.I)              #正确!
regex_net = re.compile(r'(3gnet)|(2g/3g)|(c[mt]((net)|(wap)))', re.I)   #正确!
#regex_net = re.compile(r'(3gnet)|(2g/3g)|(c[mt][net|wap])', re.I)             #错误!
#regex_net = re.compile(r'(3gnet)|(2g/3g)|(c[mt][(net)|(wap)])', re.I) #错误!
#regex_net = re.compile(r'(3gnet)|(2g/3g)|(cmnet)|(cmwap)|(ctnet)', re.I)  #太丑陋……
参考链接:
1.使用非贪婪匹配表达式时要非常注意的点!
sqli_regex1 = re.compile(r'(select|insert|update|delete).+?(where|values|set)(.+?) </', re.I|re.S)
sqli_regex2 = re.compile(r'(select|insert|update|delete).+?(where|values|set)(.+?)', re.I|re.S)
sqli_regex3 = re.compile(r'(select|insert|update|delete).+?(where|values|set)(.+?)$', re.I|re.S)

第一种sqli_regex1是准确指定,没有问题;
第二种sqli_regex2就存在问题了,此处的非贪婪匹配只能匹配一个字符,而不是匹配至行尾(如果要修改的话,可以将“(.+?)”修改为“(.*?)”即可);
第三种sqli_regex3也没问题,因为手动指定了“$”行尾标识。

2.一些选项(多行匹配、忽略大小写……)
re.I
re.IGNORECASE
Perform case-insensitive matching; expressions like [A-Z] will match lowercase letters, too. This is not affected by the current locale.

re.L
re.LOCALE
Make w, W, b, B, s and S dependent on the current locale.

re.M
re.MULTILINE
When specified, the pattern character '^' matches at the beginning of the string and at the beginning of each line (immediately following each newline); and the pattern character '$' matches at the end of the string and at the end of each line (immediately preceding each newline). By default, '^' matches only at the beginning of the string, and '$' only at the end of the string and immediately before the newline (if any) at the end of the string.

re.S
re.DOTALL
Make the '.' special character match any character at all, including a newline; without this flag, '.' will match anything except a newline.( re.S 即为 '.' 并且包括换行符在内的任意字符 )

re.U
re.UNICODE
Make w, W, b, B, d, D, s and S dependent on the Unicode character properties database.(New in version 2.0.)
3.将多行字符串转换成单行字符串(去掉行内连续的多个空白字符——换行符、空格、Tab符号)

x = string.join(multi_line_str.split(), ‘ ‘)
即,先str.split,然后再string.join()(注意第二个是string.join()而不是str.join())
https://docs.python.org/2/library/stdtypes.html#str.split
https://docs.python.org/2/library/string.html#string.join

参考链接:

《 “正则表达式中的一些tips[慢慢积累]” 》 有 2 条评论

  1. 想写出效率更高的正则表达式?试试固化分组和占有优先匹配吧
    https://mp.weixin.qq.com/s/ezul6Dg4f6_WLHXAkEgd6g
    https://www.regular-expressions.info/possessive.html
    `
    首先,占有优先的匹配方式跟贪婪匹配的方式很像。它们之间的区别就是「占有优先的匹配方式,不会归还已经匹配的字符」,这点很重要。这也是为什么「占有优先的匹配方式效率比较高的原因。因为它作用的表达式在匹配结束之后,不会保留备用的状态,也就是不会进行回溯」。但是,贪婪匹配会保留备用的状态,如果之前的匹配没有成功的话,它会回退到最近一次的保留状态,也就是进行回溯,「以便正则表达式整体能够匹配成功」。那么占有优先的表示方式是怎样的?「占有优先匹配就是在原来的量词的后面添加一个+」。

    在开始匹配的过程中「我们可以把占有优先当做贪婪匹配来进行匹配,但是一旦匹配完成就跟贪婪匹配不一样了,因为它不再归还匹配到的字符」。所以对于占有优先的匹配方式,我们只需要牢记「占有优先匹配方式匹配到的字符不再归还」就可以了。
    `

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注