Bash正则表达式匹配子串与精确整数范围

时间:2015-05-21 13:00:19

标签: regex bash

我需要匹配包含任何

的字符串$str
foo{77..93}

并捕获变量中的上述子字符串。 到目前为止,我已经:

str=/random/string/containing/abc-foo78_efg/ # for example
if [[ $str =~ (foo[7-9][0-9]) ]]; then
    id=${BASH_REMATCH[1]}
fi
echo $id # gives foo78

但这也会捕获目标范围之外的ID(例如foo95)。 有没有办法将正则表达式限制在一个精确的整数范围内? (尝试foo[77-93],但这不起作用。

由于

2 个答案:

答案 0 :(得分:6)

如果你想使用正则表达式,你将不得不使它更复杂:

if [[ $str =~ foo(7[7-9]|8[0-9]|9[0-3]) ]]; then
    id=${BASH_REMATCH[0]}
fi

请注意,我已经删除了整个模式周围的捕获组,现在使用匹配数组的第0个元素。

顺便说一下,为了最大程度地兼容旧版本的bash,我建议将模式分配给变量并在测试中使用如下:

re='foo(7[7-9]|8[0-9]|9[0-3])'
if [[ $str =~ $re ]]; then
    id=${BASH_REMATCH[0]}
fi

使用正则表达式的另一种方法是使用算术上下文,如下所示:

if (( "${str#foo}" >= 77 && "${str#foo}" <= 93 )); then
    id=$str
fi

这剥夺了&#34; foo&#34;从变量的开头部分,以便可以用数字比较整数部分。

答案 1 :(得分:1)

Perl很容易做到:

$ echo foo{1..100} | tr ' ' '\n' | perl -lne 'print $_ if m/foo(\d+)/ and $1>=77 and $1<=93'
foo77
foo78
foo79
foo80
foo81
foo82
foo83
foo84
foo85
foo86
foo87
foo88
foo89
foo90
foo91
foo92
foo93

awk偶:

$ echo foo{1..100} | tr ' ' '\n' | awk -F 'foo' '$2>=77 && $2<=93
 {print}'
foo77
foo78
foo79
foo80
foo81
foo82
foo83
foo84
foo85
foo86
foo87
foo88
foo89
foo90
foo91
foo92
foo93