需要一个可以处理可选子串的正则表达式

时间:2014-03-26 16:35:17

标签: regex sed

我正在尝试使用sed来解析git describe输出中的版本号。输出格式为:

vMAJOR.MINOR[-STRING]-REVISION-HASH

MAJORMINORREVISION是整数。 STRINGHASH是任意字符串,但我只对HASH感兴趣。

示例:

v0.1-alpha-3-g9c8c402应该返回0 1 3 g9c8c402

v0.4-beta-10-g3187e7f-dirty应该返回0 4 10 g3187e7f-dirty

v1.0-0-fe35119e应该返回1 0 0 fe35119e

我最初使用的是:

sed 's/v\([0-9]*\)\.\([0-9]*\)-.*-\([0-9]*\)-\(.*\)/\1 \2 \3 \4/g'

但是,它仅在存在可选子字符串时才有效。

3 个答案:

答案 0 :(得分:1)

它现在不起作用,因为它期望版本结束修订版之间有两个破折号,即使没有字符串也存在。

编辑:我对sed正则表达式不太熟悉,您需要\?而不是?。我还读到\?仅作为GNU扩展包含在内,因此不确定它是否对您有帮助。

v\([0-9]*\)\.\([0-9]*\)-.*-\?\([0-9]*\)-\(.*\)

如果\?不起作用,您可以尝试将其指定为“零次或一次”,如下所示:

v\([0-9]*\)\.\([0-9]*\)-.*-\{0,1\}\([0-9]*\)-\(.*\)

答案 1 :(得分:0)

尝试:

sed 's/v\([0-9]*\)\.\([0-9]*\)-\([^-]*-\)*\([0-9]*\)-\(.*\)/\1 \2 \4 \5/g' 

答案 2 :(得分:0)

使用bash正则表达式:

while read version; do
    if [[ $version =~ ^v([0-9]+)\.([0-9]+)(-[^-]+)?-([0-9]+)-(.+) ]]; then
        echo "${BASH_REMATCH[1]} ${BASH_REMATCH[2]} ${BASH_REMATCH[-2]} ${BASH_REMATCH[-1]} "
    fi
done <<END
v0.1-alpha-3-g9c8c402 
v0.4-beta-10-g3187e7f-dirty 
v1.0-0-fe35119e 
END
0 1 3 g9c8c402 
0 4 10 g3187e7f-dirty 
1 0 0 fe35119e

Perl的非捕获括号(?:...) 也很有用:

perl -pe 's/^v([0-9]+)\.([0-9]+)(?:-[^-]+)?-([0-9]+)-(.+)/$1 $2 $3 $4/' <<END
v0.1-alpha-3-g9c8c402 
v0.4-beta-10-g3187e7f-dirty 
v1.0-0-fe35119e 
END