子字符串和正则表达式

bev*_*bev 5 bash regular-expression

我有一个包含在变量中的字符串,我想根据相对于另一个子字符串的位置提取子字符串。除非将字符串作为 arg 发送到函数,否则我的解决方案似乎有效。我正在使用 bash shell。

#!/usr/bin/bash

var0="-a check one two three"
var1="check"

function getsubstr() {
echo ${*#*"${2}"} 
}

# this prints 'one two three' which is what I want
echo ${var0#*"${var1}"}

# this prints '-a one two three', not what I want.
getsubstr $var0
Run Code Online (Sandbox Code Playgroud)

请注意,当我放入echo $*getsubstr函数时,它会打印与$var0(-> '-a check one two Three')相同的字符串,而当我放入echo $2getsubstr函数时,它会打印与$var1(-> 'check')相同的字符串。因此,在我看来,我要求在两种情况下都打印相同的子字符串。

另一个难题是,如果不是echo ${*#*"${2}"}getsubstr我使用的函数中echo ${*%"${2}"*},而是得到完全相同的结果。

任何帮助理解这种行为将不胜感激。

顺便说一句,我意识到 ${*:3}getsubstr函数内部可以返回我想要的子字符串,但我试图理解#*<regexp>%<regextp>*行为。

Pet*_*r.O 6

getsubstr $var0正在将 5 个参数传递给函数。
此外,$* 和 $@ 测试每个单独的$1 $2 等等。 arg 针对#模式。

关于 RegEx in bash:我在最后添加了一些示例,顺便说一句,'*'在正则表达式上下文中使用时只是一个特殊的正​​则表达式字符,即。使用时 =~。在您第一次使用 * in 时${*,星号的特殊用途是作为var的(伪)名称,它扩展为所有 var 的串联: $1 $2 $...etc...
您第二次使用星号,in #*"${2}", 意味着“$2”前面有任何东西,包括 nothing,将分别/单独地与每个传递的 $1 等 arg 匹配。

以下脚本可能有助于 $@ 和 $* (通过示例)...

#!/bin/bash
#   
getsubstr() {
  echo -n " ${#@} args";
  [[ "$1$2$3$4$5$6" == *\ * ]] && echo " (with embedded spaces)" || echo " (no spaces)"
  echo '                  "${*}"          '\|"${*}"\|
  echo '                   ${*}           '\|${*}\|
  echo '                  "${@}"          '\|"${@}"\|
  echo '                   ${@}           '\|${@}\|
  echo '                  "${*#*"${2}}"   '\|"${*#*"${2}"}"\|
  echo '                   ${*#*"${2}}    '\|${*#*"${2}"}\|
  echo '                  "${@#*"${2}}"   '\|"${@#*"${2}"}"\|
  echo '                   ${@#*"${2}}    '\|${@#*"${2}"}\|
  echo '                        ${*#B}    '\|${*#B}\|
  echo '                       "${*#B}"   '\|"${*#B}"\|
  echo '                        ${@#B}    '\|${@#B}\|
  echo '                       "${@#B}"   '\|"${@#B}"\|
}
var0="a B c      "
echo
echo -n "Passing "; getsubstr "$var0" ; echo
echo -n "Passing "; getsubstr  $var0  ; echo
echo -n "Passing "; getsubstr "$var0" "$var0" ; echo
echo -n "Passing "; getsubstr  $var0   $var0  ; echo
echo
exit 
###################################################################
Run Code Online (Sandbox Code Playgroud)

正则表达式 bash

# Regex checks: "=~" uses extended regular expression
#+  Parenthesized subexpressions within the regular expression are saved
#+  in the array variable BASH_REMATCH
#+  $BASH_REMATCH / ${BASH_REMATCH[0]} is the string matching the entire regular expression. 
#+  ${BASH_REMATCH[n]} is the sub string matching the nth parenthesized subexpression

  [[ "abcdef" =~ (.)(.)(.) ]] && echo "# $BASH_REMATCH"
# abc

  [[ "abcdef" =~ (.)(.)(.) ]] && echo "# ${BASH_REMATCH[0]}"
# abc

  [[ "abcdef" =~ (.)(.)(.) ]] && echo "# ${BASH_REMATCH[2]}"
# b

  [[ "abcdef" =~ (.)(.)(.) ]] && echo "# ${BASH_REMATCH[@]}"
# abc a b c
Run Code Online (Sandbox Code Playgroud)