PostgreSQL连接字符串的正则表达式

huangapple go评论73阅读模式
英文:

Regex of PostgreSQL Connection String

问题

我正在编写一个用于捕获PostgreSQL连接字符串的正则表达式。连接字符串的格式如下:

(postgresql|postgres)://[userspec@][hostspec][/dbname][?paramspec]

其中,userspec是:user[:password]
hostspec是:[host][:port][,...]
paramspec是:name=value[&...]

这里,userspec、port、dbname和paramspec都是可选的。

连接字符串的示例如下:

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。

(postgresql|postgres):\/\/((?:[^:@]*)(?::[^@]*)?@{0,1})?(?<server>[^\/\?]+)\b

但是,当userspec不存在时,正则表达式无法正确捕获。可以在这里找到该正则表达式。

请问如何避免贪婪匹配userspec并在每一行中找到hostspec?

英文:

I am writing a regular expression for capturing the connection string of PostgreSQL. The format of the connection string as follows:

(postgresql|postgres)://[userspec@][hostspec][/dbname][?paramspec]

where userspec is: user[:password]
and hostspec is: [host][:port][,...]
and paramspec is: name=value[&...]

Here, the userspec, port, dbname and paramspec are optional.

The examples of the connection strings are as follows:

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

I tried to formulate the below regular expression to capture the connection string and in addition capture the hostspec in a capturing group.

(postgresql|postgres):\/\/((?:[^:@]*)(?::[^@]*)?@{0,1})?(?<server>[^\/\?]+)\b

However, the regex could not capture properly when userspec is not present. The regex can be found here.

Can you please point out on how to avoid the greedy evaluation of userspec and find the hostspec in each line?

答案1

得分: 2

以下是对你的正则表达式进行的一些修正,以使其按照你的期望工作。

  • (?:[^:@]*) 可以简化为 [^:@]*。如果你不将它作为一个组使用,也不需要将它放在括号内并使用 ?: 使其成为非捕获组。还添加了 \s 以防止它匹配任何换行符。
  • (?::[^@]*)? 改为 (?::[^@\s]*)?,以包括 \s,出于上述原因。
  • @{0,1} 改为 @,因为它是必需的。此外,你可以将 @{0,1} 简写为 @?
  • 在服务器组的最后,[^\/\?]+ 改为 [^\/\?\s]+,再次包括 \s

通过上述更改,它似乎可以按照你的期望工作。

更新的正则表达式演示

如果这对你有用,请告诉我。

英文:

Following are some corrections done on your regex to make it work as you expected.

  • (?:[^:@]*) can be simplified to [^:@]*. You don't need to put it within brackets and then make it non-group using ?: if you aren't doing anything with it as a group. Also added \s within it so it doesn't crawl to eat any newlines
  • (?::[^@]*)? changed to (?::[^@\s]*)? to include \s for above reason
  • @{0,1} changed to @ as its needed. Also, you can write @{0,1} as simply @?
  • Last in server group, [^\/\?]+ changed to [^\/\?\s]+ to again include \s

And with the above changes it seems to be working like you expected.

Updated Regex Demo

Let me know if this works for you.

答案2

得分: 1

另一个解决方案 (regex101):

(postgres(?:ql)?):\/\/(?:([^@\s]+)@)?([^\/\s]+)(?:\/(\w+))?(?:\?(.+))?
英文:

Another solution (regex101):

(postgres(?:ql)?):\/\/(?:([^@\s]+)@)?([^\/\s]+)(?:\/(\w+))?(?:\?(.+))?

huangapple
  • 本文由 发表于 2023年7月28日 02:13:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76782421.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定