#!/bin/bash
inputline="abc123ABC123abc,xyz890XYZ890xyz"
checkABC ()
{
local teststring="$1"
local pattern="([^,]+),(.*)"
if [[ $teststring =~ $pattern ]]; then
echo "${BASH_REMATCH[1]}; ${BASH_REMATCH[2]}"
checkNum ${BASH_REMATCH[1]}
checkNum ${BASH_REMATCH[2]}
fi
}
checkNum ()
{
if [[ $1 =~ [a-z]+([0-9]+)[A-Z]+([0-9]+)[a-z]+ ]]; then
echo "${BASH_REMATCH[1]}; ${BASH_REMATCH[2]}"
fi
}
set -x
checkABC $inputline
这将给出以下输出,我们可以看到,如何被函数覆盖。
${BASH_REMATCH[2]}
我知道,我可以通过将重新匹配的结果复制到另一个数组来防止这种情况,我可以在本地处理并应用
checkNum
(请参见下面的示例)。这是这样做的聪明方法,还是有一种更好的方法来防止从功能中泄漏出来? thiscode
$ bash ./leaking.sh
+ checkABC abc123ABC123abc,xyz890XYZ890xyz
+ local teststring=abc123ABC123abc,xyz890XYZ890xyz
+ local 'pattern=([^,]+),(.*)'
+ [[ abc123ABC123abc,xyz890XYZ890xyz =~ ([^,]+),(.*) ]]
+ echo 'abc123ABC123abc; xyz890XYZ890xyz'
abc123ABC123abc; xyz890XYZ890xyz
+ checkNum abc123ABC123abc
+ [[ abc123ABC123abc =~ [a-z]+([0-9]+)[A-Z]+([0-9]+)[a-z]+ ]]
+ echo '123; 123'
123; 123
+ checkNum 123
+ [[ 123 =~ [a-z]+([0-9]+)[A-Z]+([0-9]+)[a-z]+ ]]
像我想要的那样的执行:
checkNum
hack的位置,但由于它仅是当前外壳的本地,您可以在函数中运行一个子壳。
BASH_REMATCH
或
#!/bin/bash
inputline="abc123ABC123abc,xyz890XYZ890xyz"
checkABC ()
{
local teststring="$1"
local pattern="([^,]+),(.*)"
local -a storeRematch
if [[ $teststring =~ $pattern ]]; then
storeRematch=("${BASH_REMATCH[@]}")
echo "${storeRematch[1]}; ${storeRematch[2]}"
checkNum ${storeRematch[1]}
checkNum ${storeRematch[2]}
fi
}
checkNum ()
{
if [[ $1 =~ [a-z]+([0-9]+)[A-Z]+([0-9]+)[a-z]+ ]]; then
echo "${BASH_REMATCH[1]}; ${BASH_REMATCH[2]}"
fi
}
set -x
checkABC $inputline
这将使BASH_REMATCH始于全局到两个函数。
除此之外,我认为将其分配给另一个阵列是您将要获得的最好的(因为它没有打开新的过程/子壳)。
bash ./notleaking.sh
+ checkABC abc123ABC123abc,xyz890XYZ890xyz
+ local teststring=abc123ABC123abc,xyz890XYZ890xyz
+ local 'pattern=([^,]+),(.*)'
+ local -a storeRematch
+ [[ abc123ABC123abc,xyz890XYZ890xyz =~ ([^,]+),(.*) ]]
+ storeRematch=("${BASH_REMATCH[@]}")
+ echo 'abc123ABC123abc; xyz890XYZ890xyz'
abc123ABC123abc; xyz890XYZ890xyz
+ checkNum abc123ABC123abc
+ [[ abc123ABC123abc =~ [a-z]+([0-9]+)[A-Z]+([0-9]+)[a-z]+ ]]
+ echo '123; 123'
123; 123
+ checkNum xyz890XYZ890xyz
+ [[ xyz890XYZ890xyz =~ [a-z]+([0-9]+)[A-Z]+([0-9]+)[a-z]+ ]]
+ echo '890; 890'
890; 890
是一个可读的变量,因此诸如checkNum ()
{
(
if [[ $1 =~ [a-z]+([0-9]+)[A-Z]+([0-9]+)[a-z]+ ]]; then
echo "${BASH_REMATCH[1]}; ${BASH_REMATCH[2]}"
fi
)
}
not之类的东西可以工作。
(
checkNum ${BASH_REMATCH[1]}
checkNum ${BASH_REMATCH[2]}
)
在您的情况下 - 只是提及 - 您可以使用:
BASH_REMATCH
我知道这很古老,但是我本人遇到了同样的问题,进行了一些谷歌搜索并遇到了此页。安德烈亚斯(Andreas)关于bash_rematch仅阅读的建议使我找到了解决方案。
Bash_rematch是不读取:
但它是全局的,因此对其进行修改的函数调用可能会引起混乱。但是您可以使用局部变量来保存bash_rematch,然后调用
local re
re=("${BASH_REMATCH[@]}")
,然后在此简化示例中还原bash_rematch,如:# teststring="1234,5678"
checkNum "${teststring%%,*}" # 1234
checkNum "${teststring#*,}" # 5678