问题描述
根据man zshexpn
(5.0.2):
According to man zshexpn
(5.0.2):
~ 将字符串参数强制到括号内的以下任何标志被视为模式.
例如,使用 s
标志执行字段拆分需要一个字符串参数:
For example, using the s
flag to perform field splitting requires a string argument:
% print -l ${(s:9:):-"foo893bar923baz"}
foo8
3bar
23baz
我对 ~
标志的阅读表明我应该能够指定一个模式来代替要拆分的文字字符串,以便以下内容
My reading of the ~
flag suggests that I should be able to specify a pattern in place of a literal string to split on, so that the following
% print -l ${(~s:<->:):-"foo893bar923baz"}
应该产生
foo
bar
baz
相反,它的行为与我省略了 ~
一样,完全不执行拆分.
Instead, it behaves the same as if I omit the ~
, performing no splitting at all.
% print -l ${(s:<->:):-"foo893bar923baz"}
foo893bar923baz
% print -l ${(~s:<->:):-"foo893bar923baz"}
foo893bar923baz
推荐答案
好的,重新看问题,这就是区别:
Ok, rereading the question, it's the difference between this:
$ val="foo???bar???baz"
$ print -l ${(s.?.)val}
foo
bar
baz
还有这个:
$ val="foo???bar???baz"
$ print -l ${(~s.?.)val}
foo???bar???baz
它对变量进行操作,即拆分的参数"(来自您的文档引用).在第一个示例中,我们替换文字 ?
,在第二个示例中,我们将变量视为一个 glob,并且没有文字 ?
,因此没有任何内容被替换.
It operates on the variable, i.e. the "argument" to the split (from your documentation quote). In the first example, we substitute literal ?
, and in the second, we treat the variable as a glob, and there are no literal ?
, so nothing gets substituted.
不过,split 仍然适用于字符而不是替换本身中的 glob,来自 文档:
Still, though, split works on characters and not globs in the substution itself, from the documentation:
s:string:
Force field splitting (see the option SH_WORD_SPLIT) at the separator string.
因此,您似乎无法按模式拆分.~
字符修改要拆分的字符串的解释.
So, it doesn't look like you can split on a pattern. The ~
character modifies the interpretation of the string to be split.
此外,从您引用的相同模式扩展文档中,它继续:
Also, from the same pattern expansion documentation you reference, it continutes:
与括号外的 ~ 比较,强制整个要被视为模式的替换字符串.[[?"= ${(~j.|.)array} ]]设置 EXTENDED_GLOB 选项成功,如果和仅当 $array 包含字符串?"作为元素时.论证可能重复以切换行为;它的效果只持续到最后括号中的组.
${(~j.|.)array}
和 ${(j.|.)~array}
的区别在于前者对值的处理inarray
作为全局变量,后者将 结果 视为全局变量.
The difference between ${(~j.|.)array}
and ${(j.|.)~array}
is that the former treats the values inarray
as global, and the latter treats the result as a glob.
另见:
${~spec}
开启 GLOB_SUBST 选项来评估spec;如果'~' 加倍,将其关闭.设置此选项后,字符串扩展产生的结果将被解释为任何地方的模式这是可能的,例如在文件名扩展和文件名中生成和模式匹配上下文,例如条件中的="和!="运算符.
以下是显示差异的演示:
Here is a demo that shows the differences:
$ array=("foo???bar???baz" "foo???bar???buz")
$ [[ "foo___bar___baz" = ${(~j.|.)array} ]] && echo true || echo false
false
$ [[ "foo___bar___baz" = ${(j.|.)~array} ]] && echo true || echo false
true
为了完整性:
$ [[ "foo___bar___baz" = ${(~j.|.)~array} ]] && echo true || echo false
true
这篇关于~参数扩展标志的正确用法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!