PostgreSQL连接字符串正则优化:hostspec捕获异常问题求助
优化PostgreSQL连接字符串正则以正确捕获hostspec
连接字符串格式规则
PostgreSQL连接字符串格式定义:
(postgresql|postgres)://[userspec@][hostspec][/dbname][?paramspec]各部分说明:
- userspec:
user[:password](可选)- hostspec:
[host][:port][,...](核心捕获目标)- paramspec:
name=value[&...](可选)
port、dbname同样为可选内容
测试用连接字符串示例
postgresql://localhost postgresql://localhost:5433 postgresql://localhost/mydb postgresql://user@localhost postgresql://user:secret@localhost postgresql://other@localhost/otherdb?connect_timeout=10&application_name=myapp postgresql://host1:123,host2:456/somedb?application_name=myapp postgres://myuser:mypassword@192.168.0.100:5432/mydatabase postgresql://192.168.0.100/mydb
现有正则问题
原正则尝试捕获hostspec,但在无userspec时无法正确匹配:
(postgresql|postgres):\/\/((?:[^:@]*)(?:[^@]*)?@{0,1})?(?<server>[^\/\?]+)\b
问题根源在于userspec部分的匹配逻辑混乱,当没有@分隔符时,错误地将hostspec内容纳入userspec的可选组,导致server捕获组无法正确取值。
优化后的正则方案
调整匹配逻辑,通过优先匹配带@的userspec,再处理无userspec的场景,彻底避免贪婪匹配干扰:
(postgresql|postgres):\/\/(?:([^@]+)@)?(?<server>[^\/?]+)
逻辑说明
(postgresql|postgres):\/\/: 匹配固定的连接串协议头(?:([^@]+)@)?: 可选的userspec匹配,[^@]+精准匹配不含@的用户信息(含密码),?:标记为非捕获组,外层?表示整个userspec为可选(?<server>[^\/?]+): 捕获hostspec,[^\/?]+匹配所有不含/和?的内容,正好对应到dbname或参数前的主机部分
验证效果
该正则可正确适配所有测试示例:
- 无userspec时(如
postgresql://localhost),server组直接捕获localhost - 含userspec时(如
postgres://myuser:mypassword@192.168.0.100:5432/mydatabase),server组捕获192.168.0.100:5432 - 多主机场景(如
postgresql://host1:123,host2:456/somedb?application_name=myapp),server组捕获host1:123,host2:456
内容的提问来源于stack exchange,提问作者Setu Kumar Basak
相关产品推荐
相关产品推荐

