我们早先说过分隔符不会被返回,但是如果 PATTERN 包含圆括弧,那么每一对圆括弧匹配的子字串都会包括在结果列表中,分散在那些平常返回的域之中。下面是一个简单的例子:
split /([-,])/, "1-10,20";
生成列表:
(1, '-', 10, ',', 20)
如果有更多圆括弧,那么为每个圆括弧对返回一个域,即使有些圆括弧对没有匹配也如此,这种情况下,为那些位置返回未定义数值。因此,如果你说:
split /(-)|(,)/, "1-10,20";
那么结果是:
(1, '-', undef, 10, undef, 20);
/PATTERN 参数的位置可以放这么一个表达式,该声明在运行时生成不同的模式。和普通模式一样,如果想只做一次运行时编译,那么用 /$varable/o。
有一个特殊的情况,如果该表达式是一个空格(“ ”),那么该函数会象没有参数的 split 那样在空格上把字串开。因此 split(" ") 可以用于模拟 awk 的缺省行为。相反,split(/ /)将给你和前导空格一样多的空的初始化域。(除了这个特殊的例子以外,如果你提供的是一个字串而不是一个正则表达式,那么它还是会被解释成一个正则表达式。)你可以用这个属性把开头和结尾的空白删除,并且把中间的空白都压缩成一个空白:
$string = join(' ', split(' ', $string));
下面的例子把一个 RFC 822 消息头成一个包含 $head{Date},$head{Subject},等等的散列。它使用了给一个散列赋予一个配对列表的技巧,理由是域和分隔符交错。它利用圆括弧把每个分隔符的一部分当作返回列表值的一部分返回。因为 split 模式保证把返回的东西利用包含圆括弧的好处按照配对的形式返回,所以散列赋值就可以保证收到一个包含键字/数值对的列表,这里每个键字就是一个头域的名字。(糟糕的是,这个技巧会丢失有着相同域的多个行的信息,比如 Received-By 行。啊,哦...)
$header =~ s/\n\s+/ /g; # 融合连续行
%head = ('FRONTSTUFF', split /^(\S*?):\s*/m, $header);
下面的例子处理整个 Unix passwd(5) 文件。你可以忽略 chomp,这个时候 $shell 的结尾将有换行符。
open PASSWD, '/etc/passwd'; while () { chomp; # 删除结尾的换行符 ($login, $passwd, $uid, $gid, $gcos, $home, $shell) = split /:/; ... }
下面是一个如何处理每个输入文件里的每一行中的每个词,创建一个单词频率散列的例子:
while (<>) {
foreach $word (split) {
$count{$word}++;
}
}
split 的逆操作由 join 执行(只不过 join 只能在所有域之间用同样的分隔符连接)。要用固定位置的域分解字串,请使用 unpack。
sprintf FORMAT, LIST
这个函数返回一个格式化字串,格式化习惯是 C 的库函数 sprintf 的是 printf 习惯。参阅你的系统的 sprintf(3) 或 printf (3) 获取一些通用原则的解释。FORMAT 包含一个带有嵌入的域指示符的文本,LIST 里的元素就是逐一替换到这些域中去的。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-28372-12.html
好漂亮
什么船撞得过他