正则的定界符并非只可以用 / 号 ¶
作者:KK
发表日期:2019.08.21
- 要点速读:
#http://xxx\.com#
和/http:\/\/xxx\.com/
这两个正则的匹配效果是一模一样的,而且前者更简洁。
多年来偶尔上网查一些正则时,看到大部分文章的正则并没有以最简洁的方式写出来,其中一个啰嗦的地方就是这样的:preg_match('/http:\/\/xxx\.com/', $var)
,其实这个代码可以简化成preg_match('#http://xxx\.com#', $var)
,个人觉得这样看起来很直观,少了一些黑底符的干扰,问题的本质就是:所书写的正则表达式到底用了什么定界符(左右两边的那个符号)
我认为很多人的第一习惯就是用/
号做定界符的,而作为 Web 开发者在开发过程中要匹配的内容经常都需要匹配里面的/
号,由于与定界符产生了冲突,于是内部这些被匹配的内容就需要写成\/
使得这个表达式看起来啰嗦复杂。
在PHP里,正则表达式的左右两边都需要用同样的符号,这是原则,并没有限定咱们用哪个符号,所以其实/abc\d+/
、#abc\d+#
和~abc\d+~
这样都是等效的。
但右边定界符后面倒是可以带其它修饰符,比如preg_match('#abc#i', 'Abc')
不区分大小写匹配,而preg_match('#abc#', 'Abc')
是按照大小写匹配的,区别就是右边的#
这个定界符后面多了个修饰符i
,这里并不详细讲修饰符,只是说明定界符的作用和界限而已。
而在官方文档里确实是是优先使用/
号作为定界符进行示例的,这样会导致很多开发者第一想法就是跟着用这个。其实官方用那个符号倒是有它的好处,因为在JS里也需要用定界符,如/abc\d+/.test('xabc99]]]')
和/abc\d+/ig.test('xabc99]]]')
,.
号左边的都是一整个正则对象,并且只能用/
作为定界符。PHP相关的文章也用相同的符号,可以使得大家在有需要的情况下直接将正则复制到JS代码里跑而不需要什么转换书写,然而这毕竟是很少数的需求,往往搜索JS匹配XXXX
的关键词出来都是JS的正则,而且PHP正则里的修饰符也并不完全能套用在JS身上。
认清真相,理智写代码,我提倡在PHP里用#
号作为定界符以避免内部出现\/
导致表达式啰嗦(不过如果内部有#
号要匹配时,则也需要写在\#
,只是情况很少,甚至你用~
就更少了),其中著名的Yii2这个框架在路则规则匹配时相关的路由代码都是用#
号做定界符的。