正则表达式匹配行尾

4
我希望您能用BASH正则表达式从下面的命令中提取“db”参数。然而,参数的顺序不被保证。由于某些原因,我无法完全让它正常工作。
到目前为止,我已有以下内容:
regex="--db (.*)($| --)"
[[ $@ =~ $regex ]]
DB_NAMES="${BASH_REMATCH[1]}"

# These are example lines
somecommand --db myDB --conf /var/home # should get "myDB"
somecommand --db myDB anotherDB manymoreDB --conf /home # should get "myDB anotherDB manymoreDB" 
somecommand --db myDB # should get "myDB"
somecommand --db myDB anotherDB # should get "myDB anotherDB"

您对正则表达式有什么建议吗?


我认为Bash不支持非贪婪匹配。可以尝试使用([^-]*)代替(.*),或者使用AWK或SED。 - Fabricator
为什么不使用 getoptgetopts 来解析命令行参数? - seven7e
4个回答

6
问题在于bash使用的正则表达式不包括非贪婪重复操作符(*?,+?)。因为*是贪婪的,并且没有办法告诉它不要贪婪,所以第一个括号子表达式((.*))匹配到行末的所有内容。
如果您知道要捕获的值不包含某个字符,可以通过将.替换为排除该字符的字符类来解决此问题。
例如,如果--db之后的值不包含破折号(-),则可以使用以下正则表达式:
regex='--db ([^-]*)($| --)'

它与问题中发布的所有示例都匹配。

2
以下内容有效:
regex="--db[[:space:]]([[:alnum:][:space:]]+)([[:space:]]--|$)"
[[ "$@" =~ $regex ]]

有两个问题:

  1. 应该使用类似 [:space:] 的字符类来表示空格
  2. (.*) 是贪婪的,会一直匹配到最后一个 -- 字面量。由于 bash 不支持非贪婪匹配,所以我们必须使用 [[:alnum:][:space:]] 进行匹配,这将保证我们在下一个 -- 停止匹配。

@axiac - 啊,我以为正则表达式是正确的,而引号导致了问题。我也修复了正则表达式,谢谢。 - Martin Konecny
引号不会造成任何伤害。我运行了问题中发布的代码,并且对于最后两个示例,它可以正常工作。问题出在前两个示例上,因为bash使用的regex是贪婪的,我无法找到任何方法(在文档中)使它们变得非贪婪。 - axiac

1

默认情况下,正则表达式会尝试获取尽可能多的匹配项,使用非贪婪 (懒惰) 量词。您可能还希望将 -- 放在首位,以便引擎优先使用它。

--db[[:space:]](.*?)([[:space:]]--|$)

演示


如果您不想要--,可以使用非捕获组

--db[[:space:]](.*?)(?:[[:space:]]--|$)
                     ^^ Notice the ?:

演示


1
Bash不支持非贪婪模式。 - Martin Konecny
2
Bash 也不支持非捕获组。 - axiac

0

我认为您想匹配非空格字符以捕获第一组:

regex="--db (\S+)( --|$)"

Bash不支持使用\S进行字符类匹配 - 尽管无法对正则表达式进行引用。 - Martin Konecny

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接