preg_match_all等效于BASH?

时间:2017-02-07 11:31:43

标签: regex bash

我有一个像这样的字符串

foo:collection:indexation [options] [--] <text> <text_1> <text_2> <text_3> <text_4>

我想使用bash正则表达式来获取一个数组或字符串,我可以将其拆分以获取此信息以检查语法是否正确

["text", "text_1", "text_2", "text_3", "text_4"]

我试过这样做:

COMMAND_OUTPUT=$($COMMAND_HELP)
# get the output of the help
# regex
ARGUMENT_REGEX="<([^>]+)>"
GOOD_REGEX="[a-z-]"

# get all the arguments
while [[ $COMMAND_OUTPUT =~ $ARGUMENT_REGEX ]]; do
    ARGUMENT="${BASH_REMATCH[1]}"
    # bad syntax
    if [[ ! $ARGUMENT =~ $GOOD_REGEX ]]; then
        echo "Invalid argument '$ARGUMENT' for the command $FILE"
        echo "Must only use characters [a-z:-]"
        exit 5
    fi
done

但是,因为我总是得到第一场比赛,所以这段时间似乎不合适。

如何获得此正则表达式的所有匹配项?

谢谢!

2 个答案:

答案 0 :(得分:1)

循环不起作用,因为每次你只是针对正则表达式测试相同的输入字符串。它不知道它应该在上一次迭代的匹配之后开始扫描。在进行下一次测试之前,您需要删除字符串的一部分,包括上一个匹配项。

更简单的方法是使用grep -o来获取所有匹配项。

$COMMAND_HELP | grep -o "$ARGUMENT_REGEX" | while read ARGUMENT; do
    if [[ ! $ARGUMENT =~ $GOOD_REGEX ]]; then
        echo "Invalid argument '$ARGUMENT' for the command $FILE"
        echo "Must only use characters [a-z:-]"
        exit 5
    fi
done

答案 1 :(得分:1)

Bash没有这个直接,但你可以通过稍作修改来达到类似的效果。

string='foo...'
re='<([^>]+)>'

while [[ $string =~ $re(.*) ]]; do
   string=${BASH_REMATCH[2]}

   # process as before
done

这匹配正则表达式后我们想要的正则表达式以及字符串中的所有内容。我们通过在每次迭代时仅为其指定after-our-regex部分来缩短$string。在最后一次迭代中,${BASH_REMATCH[2]}将为空,因此循环将终止。