为何PHP中可用的正则表达式转译到.NET后出现编码问题?
嘿,太懂这种感受了!我自己也算不上正则表达式的狂热信徒,但不得不承认这工具是真的好用——就是那种超长的复杂正则,看一眼脑子直接打结,完全摸不着北。
你提到的这个在PHP应用里用的URL匹配正则,我来帮你拆解一下,搞清楚它到底在干嘛:
拆解目标URL正则表达式
先把你给出的正则码出来(看起来你没写完,但核心逻辑已经很清晰了):
/^(https?|ftp)\:\/\/([a-z0-9+\!\*\(\)\,\;\?\&\=\$\_\.\-]+(\:[a-z0-9+\!\*\(\)\,\;\?\&\=\$\_\.\-]+)?@)?[a-z0-9\+\$\_\-]+(\.[a-z0-9+\$\_\-]+)*(\:[0-9]{2,5})?(\/([a-z0-9+\$\_\-]\.?)+)*\/?(\?[a-z\+\&\$\_\.\-][a-z0-9\;\:\@\/\&\%\=\+...
咱们把它拆成几个核心模块来看,就不会那么晕了:
协议匹配模块:
^(https?|ftp)\:\/\/^锚定字符串的起始位置,确保从开头就匹配(https?|ftp)精准匹配http、https或者ftp协议,s?表示s是可选的,所以http和https都能覆盖\:\/\/匹配URL里的://,这里的转义符是因为/是正则的分隔符,:属于特殊字符,必须转义才能匹配字面量
可选的用户名密码模块:
([a-z0-9+\!\*\(\)\,\;\?\&\=\$\_\.\-]+(\:[a-z0-9+\!\*\(\)\,\;\?\&\=\$\_\.\-]+)?@)?- 整个模块末尾的
?表示这部分是可选的——也就是说URL带不带用户名密码都能匹配 - 第一部分
[a-z0-9+\!\*\(\)\,\;\?\&\=\$\_\.\-]+匹配用户名,允许小写字母、数字,以及一堆特殊符号 (\:[a-z0-9+\!\*\(\)\,\;\?\&\=\$\_\.\-]+)?是可选的密码段,以:开头,后面跟和用户名规则一致的字符- 最后的
@是用户名密码的结束标记,后面接域名部分
- 整个模块末尾的
域名匹配模块:
[a-z0-9\+\$\_\-]+(\.[a-z0-9+\$\_\-]+)*- 先匹配主域名(比如
example),然后(\.[a-z0-9+\$\_\-]+)*用来匹配多级域名或者顶级域名(比如.com、.co.uk这种),*表示可以匹配0次或多次
- 先匹配主域名(比如
可选的端口模块:
(\:[0-9]{2,5})?- 匹配URL里的端口号,格式是
:后面跟2-5位数字(比如:8080、:443),?表示端口是可选的
- 匹配URL里的端口号,格式是
路径匹配模块:
(\/([a-z0-9+\$\_\-]\.?)+)*\/?- 匹配URL里的路径部分,比如
/blog/post/123,允许路径里包含字母、数字、特殊符号和点;最后的\/?表示路径末尾可以有一个可选的/
- 匹配URL里的路径部分,比如
未完成的查询参数模块:
(\?[a-z\+\&\$\_\.\-][a-z0-9\;\:\@\/\&\%\=\+...- 这部分你没写完,但看得出来是用来匹配
?开头的查询参数(比如?id=1&sort=desc),规则是匹配?后接合法的参数字符
- 这部分你没写完,但看得出来是用来匹配
说实在的,这个正则写得有点“复古”——它把所有允许的特殊字符都手动列出来了,其实现在可以用更简洁的字符类写法,但因为是在你无法控制的PHP应用里,咱们先搞懂它的逻辑就行。
如果要调试或者修改这个正则,建议用正则测试工具,把测试URL放进去一步步看匹配结果,比死啃正则文本直观多了。
内容的提问来源于stack exchange,提问作者CarComp
相关产品推荐
相关产品推荐

