站长最近在用PHP实现一个过滤敏感词汇的API,主要基于一个现成的正则表达式库。
然而这个正则表达式库是写给C#客户端的,与PHP有很多不兼容之处。
由此引申,站长在此总结一下PHP正则表达式可能会踩的坑。
不多废话,速度切入正题——
编码错误
编码错误是最易踩的坑,如果你的正则里都是英文那好说,但是如果包含中文或者特殊符号,那就要格外小心了。
如果你发现你的正则表达式在PHP里不知为何匹配不出来值,或者匹配出来的是乱码,那么你可以尝试在正则表达式分组符后面加上“u”修饰符,这样能够强制所有字符全部采用UTF-8编码规则,可以避免匹配出来的结果是乱码。
转义符错误
转义符错误也是比较容易踩的坑,当你的正则表达式内涵大量的斜杠或者反斜杠时,往往会把你搞得头晕,也很容易出转义符的错误。
不妨使用一些在线正则测试工具测试一下,效率比自行排错要高得多。
当然,这种情况下,正则表达式的分组符不建议使用斜杠”/”,可以换为“~”、“#”等便于区别的符号。
功能不兼容
在你编写正则表达式的时候,须要注意到不同语言平台上的正则表达式库都不支持部分的正则功能。如果你使用了这些功能,则会直接报Error。
一个最典型的例子就是PHP不支持零宽度正回顾后发断言,也就是不支持形如“?<!”的语法,如果你使用了,那么会直接报错,当然PHP的PREG函数报错并不会终止整个php的执行,如果不echo结果的话,很可能都不知道哪里报错了,因为PREG函数会返回一个空值。
修饰符使用不当
如果你在JS的环境中写过正则表达式,你可能接触过”/g”这种修饰符,这代表执行完全匹配,即返回所有匹配结果。
但如果尝试在PHP中写“/g”修饰符,PREG函数会直接抛一个错误。
原因是PHP中已经有一个函数叫做“preg_match_all”,这个函数与“/g”等效,因此PHP中压根不存在”/g”修饰符,添加不存在的修饰符必然会报错。
正则语法过于繁琐
以站长为例,正则表达式库有整整300kb。
如果正则表达式过于繁琐,则匹配过程会消耗大量的CPU资源。注意,正则表达式是用递归的方式搜索的,当递归长度过长就会导致阻塞或者溢出。一不小心就会导致504错误。
所以务必优化正则的语法,避免大量重复搜索和过多的零宽断言。
结束语
正则表达式是匹配字符串的绝佳方式,如今已经得到了很广泛的应用,但其复杂的语法规则是入门的一大门槛。
希望本文能对写正则表达式的各位有所帮助。