在bash使用正则表达式中的字符串多个匹配(Multiple matches in a string

2019-06-26 10:18发布

一直在寻找与bash的正则表达式的一些更高级的正则表达式的信息,并没有发现它的许多信息。

这里的概念,用一个简单的字符串:

myString="DO-BATCH BATCH-DO"

if [[ $myString =~ ([[:alpha:]]*)-([[:alpha:]]*) ]]; then
 echo ${BASH_REMATCH[1]} #first perens
 echo ${BASH_REMATCH[2]} #second perens
 echo ${BASH_REMATCH[0]} #full match
fi

outputs:
BATCH
DO
DO-BATCH

所以精细它的第一场比赛(批次DO),但我怎么拉第二场比赛(DO-批)? 我只是一片空白这里找不到bash的正则表达式的很多信息。

Answer 1:

行,所以我做了这一个办法是把它放在一个for循环:

myString="DO-BATCH BATCH-DO"
for aString in ${myString[@]}; do
    if [[ ${aString} =~ ([[:alpha:]]*)-([[:alpha:]]*) ]]; then
     echo ${BASH_REMATCH[1]} #first perens
     echo ${BASH_REMATCH[2]} #second perens
     echo ${BASH_REMATCH[0]} #full match
    fi
done

which outputs:
DO
BATCH
DO-BATCH
BATCH
DO
BATCH-DO

其工作原理,但那种我希望如果可能的话把它拉都来自同一个正则表达式。



Answer 2:

在你的答案, myString是不是一个数组,但你使用数组引用来访问它。 这适用于击因为数组的第0个元素可以通过仅变量名被称为并且反之亦然。 这也就意味着,你可以使用:

for aString in $myString; do

得到在这种情况下相同的结果。

在你的问题,你说的输出包括“批DO”。 我得到“DO-一批”所以我想这是一个错字。

只有这样,才能获得额外的字符串不使用for循环是使用更长的正则表达式。 顺便说一句,我建议把猛砸正则表达式中的变量。 这使得使用某些类型的要容易得多(那些包含空格或特殊字符,例如。

pattern='(([[:alpha:]]*)-([[:alpha:]]*)) +(([[:alpha:]]*)-([[:alpha:]]*))'
[[ $myString =~ $pattern ]]
declare -p BASH_REMATCH    #dump the array

输出:

declare -ar BASH_REMATCH='([0]="DO-BATCH BATCH-DO" [1]="DO-BATCH" [2]="DO" [3]="BATCH" [4]="BATCH-DO" [5]="BATCH" [6]="DO")'

如果你想捕捉单个子以及复姓短语需要的额外的括号。 如果您不需要个人的话,可以消除内套括号。

请注意,您不需要使用if你只需要提取子。 你只需要if根据比赛采取有条件的动作。

还要注意, ${BASH_REMATCH[0]}会有很大的不同具有较长的正则表达式,因为它包含了整场比赛。



Answer 3:

每@Dennis威廉姆森的文章中,我搞砸周围,结束了以下内容:

myString="DO-BATCH BATCH-DO" 
pattern='(([[:alpha:]]*)-([[:alpha:]]*)) +(([[:alpha:]]*)-([[:alpha:]]*))'

[[ $myString =~ $pattern ]] && { read -a myREMatch <<< ${BASH_REMATCH[@]}; }

echo "\${myString} -> ${myString}" 
echo "\${#myREMatch[@]} -> ${#myREMatch[@]}"

for (( i = 0; i < ${#myREMatch[@]}; i++ )); do   
  echo "\${myREMatch[$i]} -> ${myREMatch[$i]}" 
done

这工作得很好,除了myString的必须有2个数值在那里。 所以我张贴此,因为它是有点儿有趣与它我的乐趣搞乱。 但要获得这种更通用和地址配对组的任何量(即DO-批)我要去跟我原来的答复的修改版本:

myString="DO-BATCH BATCH-DO" 
myRE="([[:alpha:]]*)-([[:alpha:]]*)"

read -a myString <<< $myString

for aString in ${myString[@]}; do   
  echo "\${aString} -> ${aString}"  
  if [[ ${aString} =~ ${myRE} ]]; then
    echo "\${BASH_REMATCH[@]} -> ${BASH_REMATCH[@]}"
    echo "\${#BASH_REMATCH[@]} -> ${#BASH_REMATCH[@]}"
    for (( i = 0; i < ${#BASH_REMATCH[@]}; i++ )); do
      echo "\${BASH_REMATCH[$i]} -> ${BASH_REMATCH[$i]}"
    done
  fi
done

我也喜欢像多重匹配一个perlre但这工作正常。



Answer 4:

虽然这是一岁多的问题(不接受的答案),可以在正则表达式可以简化为:

myRE="([[:alpha:]]*-[[:alpha:]]*)"

通过去除内括号找到的字的小(更简洁)组DO-BATCHBATCH-DO

它为我在你18:10时间回答。 $ {BASH_REMATCH [0]}和$ {BASH_REMATCH [1]}导致2个字被找到。



文章来源: Multiple matches in a string using regex in bash
标签: bash bash4