为什么这种内部扩展模式不起作用?
Why this expansion inside expansion pattern doesn't work?
假设你有这样的东西:
$ a=(fooa foob foox)
那么你可以这样做:
$ b=(${(M)a:#*(a|b)})
到select a的元素匹配模式。
所以你有:
$ print ${(qq)b}
'fooa' 'foob'
然后你希望以某种动态方式构建模式,所以你将它放在另一个变量中,比如:
$ p="*(a|b)"
你期望这样:
$ b=(${(M)a:#$p})
如文档所述,工作方式与以前相同,但事实并非如此:
$ print ${(qq)b}
''
这是为什么?
因为在这种情况下 zsh 尝试 select $p
的字面值(纯字符串文本):
a=('*(a|b)' fooa foob)
p="*(a|b)"
b=(${(M)a:#$p})
print ${(qq)b}
;#⇒'*(a|b)'
我们可以通过 ${~spec}
形式告诉 zsh 将 $p
的扩展视为模式而不是文字值。
${~spec}
Turn on the GLOB_SUBST
option for the evaluation of spec; if the ‘~
’ is doubled, turn it off. When this option is set, the string resulting from the expansion will be interpreted as a pattern anywhere that is possible, such as in filename expansion and filename generation and pattern-matching contexts like the right hand side of the ‘=
’ and ‘!=
’ operators in conditions.
在这种情况下,我们可以这样使用它:
a=(fooa foob foox)
p="*(a|b)"
b=(${(M)a:#${~p}}) ;# tell zsh treat as a pattern for `$p`
print ${(qq)b}
;#⇒'fooa' 'foob'
注意:它在参数扩展标志 b
中给出了一些提示,用于将模式存储在变量值中:
b
Quote with backslashes only characters that are special to pattern matching. This is useful when the contents of the variable are to be tested using GLOB_SUBST
, including the ${~...}
switch.
Quoting using one of the q family of flags does not work for this purpose since quotes are not stripped from non-pattern characters by GLOB_SUBST
. In other words,
pattern=${(q)str}
[[ $str = ${~pattern} ]]
works if $str
is ‘a*b
’ but not if it is ‘a b
’, whereas
pattern=${(b)str}
[[ $str = ${~pattern} ]]
is always true for any possible value of $str
.
-- zshexpn(1): Expansion, Parameter Expansion, Parameter Expansion Flags
假设你有这样的东西:
$ a=(fooa foob foox)
那么你可以这样做:
$ b=(${(M)a:#*(a|b)})
到select a的元素匹配模式。
所以你有:
$ print ${(qq)b}
'fooa' 'foob'
然后你希望以某种动态方式构建模式,所以你将它放在另一个变量中,比如:
$ p="*(a|b)"
你期望这样:
$ b=(${(M)a:#$p})
如文档所述,工作方式与以前相同,但事实并非如此:
$ print ${(qq)b}
''
这是为什么?
因为在这种情况下 zsh 尝试 select $p
的字面值(纯字符串文本):
a=('*(a|b)' fooa foob)
p="*(a|b)"
b=(${(M)a:#$p})
print ${(qq)b}
;#⇒'*(a|b)'
我们可以通过 ${~spec}
形式告诉 zsh 将 $p
的扩展视为模式而不是文字值。
${~spec}
Turn on the
GLOB_SUBST
option for the evaluation of spec; if the ‘~
’ is doubled, turn it off. When this option is set, the string resulting from the expansion will be interpreted as a pattern anywhere that is possible, such as in filename expansion and filename generation and pattern-matching contexts like the right hand side of the ‘=
’ and ‘!=
’ operators in conditions.
在这种情况下,我们可以这样使用它:
a=(fooa foob foox)
p="*(a|b)"
b=(${(M)a:#${~p}}) ;# tell zsh treat as a pattern for `$p`
print ${(qq)b}
;#⇒'fooa' 'foob'
注意:它在参数扩展标志 b
中给出了一些提示,用于将模式存储在变量值中:
b
Quote with backslashes only characters that are special to pattern matching. This is useful when the contents of the variable are to be tested using
GLOB_SUBST
, including the${~...}
switch.Quoting using one of the q family of flags does not work for this purpose since quotes are not stripped from non-pattern characters by
GLOB_SUBST
. In other words,pattern=${(q)str} [[ $str = ${~pattern} ]]
works if
$str
is ‘a*b
’ but not if it is ‘a b
’, whereaspattern=${(b)str} [[ $str = ${~pattern} ]]
is always true for any possible value of
$str
.--
zshexpn(1): Expansion, Parameter Expansion, Parameter Expansion Flags