我正在寻找BASH正则表达式来推动“db'来自以下命令的agruments。但是,不保证参数的顺序。出于某种原因,我无法让它完全发挥作用。
到目前为止我有什么
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"
有关正则表达式的任何建议吗?
答案 0 :(得分:4)
问题是bash
使用的regex
风格不包含非贪婪的重复运算符(*?
,+?
)。因为*
是贪婪的并且没有办法告诉它不贪婪,所以第一个带括号的子表达式((.*)
)匹配到行尾的所有内容。
如果您知道要捕获的值不包含某个字符并将.
替换为排除该字符的字符类,则可以解决此问题。
例如,如果--db
之后的值不包含短划线(-
),则可以使用此regex
:
regex='--db ([^-]*)($| --)'
它匹配问题中发布的所有示例。
答案 1 :(得分:2)
以下作品:
regex="--db[[:space:]]([[:alnum:][:space:]]+)([[:space:]]--|$)"
[[ "$@" =~ $regex ]]
有两个问题:
(.*)
贪婪,并且会一直到你最后的--
字面。由于bash不支持非贪婪匹配,因此我们必须使用[[:alnum:][:space:]]
匹配,以确保我们在下一个--
停止。答案 2 :(得分:1)
默认情况下,RegEx尝试获得尽可能多的匹配,使用非贪婪的(懒惰)量词。您可能还想先放置--
,以便引擎首先使用
--db[[:space:]](.*?)([[:space:]]--|$)
<小时/> 如果您不想要
--
,则可以使用非捕获组
--db[[:space:]](.*?)(?:[[:space:]]--|$)
^^ Notice the ?:
答案 3 :(得分:0)
我认为您希望匹配非空格字符以捕获第一个分组:
regex="--db (\S+)( --|$)"