匹配以在bash中全局捕获组

匹配以在bash中全局捕获组,bash,Bash,有一个非常简单的perl脚本: use strict; use feature 'say'; use warnings; my $str = q{some [values] in string [enclosed] [in some] number of [square brackets]}; my @matches; if(my $num =(@matches)= $str =~ / \[ (.*?) \] /gsx ) { say "got $num matches:";

有一个非常简单的perl脚本:

use strict;
use feature 'say';
use warnings;

my $str = q{some [values] in string [enclosed] [in some] number of [square brackets]};
my @matches;
if(my $num =(@matches)= $str =~ / \[ (.*?) \] /gsx ) {
        say "got $num matches:";
        say "[$_]" for @matches;
}
它打印:

got 4 matches:
[values]
[enclosed]
[in some]
[square brackets]
如何在
bash
中实现类似的功能

Ps:没有提供任何bash代码,因为我甚至不知道如何启动。
${BASH_REMATCH[@]}
不能在一行中全局运行。。。要使用
BASH\u重新比赛
需要提前知道cature组的数量。所以,我不知道…:(我能做的最接近的事情是:

str='some[values]在字符串[included][some]中[方括号]的数量'
回显“$str”

mapfile-t arr<
bash
正则表达式匹配不提供此支持。您需要通过迭代不断缩小的输入字符串来模拟它

str='some [values] in string [enclosed] [in some] number of [square brackets]'

# Match a string consisting of anything *except* ]
# between literal [ and ]
regex='\[[^]]+\]'
while [[ $str =~ $regex ]]; do
    m=${BASH_REMATCH[0]}
    echo "$m"
    str=${str##*"$m"}  # Remove the longest prefix ending with the match
done
从技术上讲,您不需要捕获组,只需要与要捕获的字符串完全匹配的正则表达式,因为
=~
将与第一个字符串匹配。

在bash中:

对于少量匹配,您可以使用:

#!/bin/bash
a='some [values] in string [enclosed] [in some] number of [square brackets]'
reg='[^[]*\[([^]]*)\]'
regex="$reg$reg$reg$reg"
[[ $a =~ $regex ]]
printf '%s\n' "${BASH_REMATCH[@]:1}"; echo
reg选择一个

  • 没有
    [
    [^[]*
  • 后跟一个
    [
  • 然后是几个非
    ]
    [^]]*
  • 后跟一个
    ]
括号表示括号内的值

在正则表达式中重复使用reg可以捕获括号内的几个字符串。这可以扩展到(少量)匹配项。对于一般解决方案,您需要一个循环或使用awk

执行时,上面的脚本将打印:

$ ./script
values
enclosed
in some
square brackets

很好的技巧。只需要删除最短的前缀
${str#*“$m”}
,因为例如对于字符串
x[a]x[a]x[a]x[c]
它将只打印
ac
,而不是
abac
$ ./script
values
enclosed
in some
square brackets