匹配BASH中的每个正则表达式实例

时间:2014-01-16 10:46:21

标签: regex bash

我想知道是否可以将BASH二元运算符=~BASH_REMATCH一起使用,以仅匹配给定字符串中正则表达式的每个实例。

例如,我尝试从字符串中获取每组数字:

string="something 123 45 bla bla some OTHER characters 6789"
[[ $string =~ [0-9]{1,4} ]] && echo ${BASH_REMATCH[0]}

我希望${BASH_REMATCH[0}123 45 6789,但它只匹配给我[0-9]{1,4}的正则表达式123的第一个实例。

我是否可以仅使用BASH完成此操作,而无需做一些有点复杂的事情?

我想避免以下类型的解决方案:

string="something 123 45 bla bla some OTHER characters 6789"
regex="([0-9]{1,4})"
[[ $string =~ ${regex}.*${regex} ]]
read -a s <<< "${BASH_REMATCH[0]}"
d=()
for i in ${s[@]}; do
    if [[ $i =~ $regex ]]; then
        d+=($i)
    fi
done
echo "The match I want is ${d[@]}"

我可以ruby

string.scan(/(\d{1,4})/)

它会匹配我想要的。

BASH是否有更简单的解决方法?

2 个答案:

答案 0 :(得分:2)

BASH_REMATCH并不像您期望的那样工作,即吐出多个匹配而不将其捕获到组中。您可以修改脚本以让函数处理它:

string="something 123 45 bla bla some OTHER ch4r4ct3rs 6789"
regex="\b([0-9]{1,4})\b"

foo() {
  while [[ $1 ]]
  do
    [[ $1 =~ $regex ]] && "${BASH_REMATCH[1]}"
    shift
  done
}

foo $string

执行此操作会产生:

123
45
6789

或者,您可以使用grep

grep -oP "$regex" <<< "$string"

答案 1 :(得分:1)

使用Gnu Awk版本4,你可以这样做:

string="something 123 45 bla bla some OTHER ch4r4ct3rs 6789"
gawk '/^[0-9]{1,4}$/' RS="[[:space:]]+" <<<"$string"

输出:

123
45
6789

(对于早期版本的gawk,您可能必须使用切换--re-interval