我正在尝试创建一个过滤器,该过滤器应该从数组中排除所有项目,除了那些与子字符串排除模式匹配的项目。
鉴于
myArr=(mySrv-dev-east-prj1 mySrv-dev-west-prj1 mySrv-qa-east-prj2 mySrv-qa-west-prj2 mySrv-uat-prd-east-prj3 mySrv-uat-prd-west-prj3 mySrv-prd-east-prj4 mySrv-prd-west-prj4)
if [[ ${myEnvSelection:l} == 'prod' ]] then
setopt extended_glob
needle_env="prd~uat"
else
needle_env=${myEnvSelection:l}
fi
needle=*${needle_env:l}*${region:l}* # *prd~uat*east*
filtered_result=(${(M)myArr:#$~needle})
unsetopt extended_glob
当我 时,我得到了所有 uat-prd 和 prd 项目 (4) setopt extended_glob
。但如果不设置,则不会返回任何项目。如果我设置,needle=*prd*east*
我将获得east
uat-prd 和 prd 的版本。我也试过了needle=*prd*east*~uat
,它返回了 2 个项目 (uat-prd-east 和 prd-east)。
我知道我误解了如何做这个模式,但我不确定下一步应该尝试什么。
将匹配和排除过滤器放入括号内的组中似乎有效:
像 这样的模式
(*prd~*uat-prd)*east*
在括号组中包含初始通配符。这很重要 - 总是*
“贪婪”,并“消耗” 之前的字母prd
。因此,与 的负向比较uat
使用*
来倒回以包含前面的字符。类似地,排除模式可以应用于整个字符串,例如
*prd*east*~*uat*
。但这种模式过于广泛,危险;像 这样的字符串mySrv-prd-east-uatproj
也会从数组中过滤掉,尽管这可能不是我们的本意。prd~uat
prd
匹配任何且 不 的字符串uat
。因此,这与单独使用相同prd
。*prd~uat*east*
匹配以 结尾prd
且不以 开头的任何字符串,uat
后面跟着包含east
*prd*east*~uat
匹配按该顺序包含prd
和east
且不为 的任何内容uat
。当然,包含prd
和的任何内容都east
不能为uat
,因此它与 相同*prd*east*
。如果您想要以 结尾
prd
但不包含 的东西uat
,然后后面跟着包含 的东西east
,那就是(*prd~*uat*)*east*
或(^*uat*)prd*east*
。uat
从您的示例来看,这些/east
/似乎prd
是-
-delimited 并且-uat
位于 之前-prd
和-east-
之后prd
。为了避免uat
在Guatemala
服务器名称中匹配,并east
在 中匹配beast
,您可以更明确地执行(^*-uat)-prd-east-*
which 匹配任何不以 结尾的内容,-uat
后跟-prd-east-
任何内容(甚至包含-uat-
)。