分类:
2008-11-25 16:42:03
你想将字符串中的制表符转换为合适数目的空格,或者是反过来。当文件中有许多连续空格的时候,将它们转换为制表符可以使文件变小。将制表符转换为空格有时也是必要的:当你的输出设备无法处理制表符,或者和你想要的位置效果不一样的时候。
你可以使用一个看起来很怪异的表达式替换:
|
或者使用标准模块 Text::Tabs:
|
假定制表符每 N 格放一个(默认情况下 N 是8),那么将它们换成空格很容易。标准的教科书式方法并不使用 Text::Tabs 模块,不过有点难于理解。而且它使用 $` 变量,每次在匹配中使用它都会降低运行速度。在第六章特殊变量中对此有所讲述。你可以用如下算法来将输入中的指标符换成 8 格空格:
|
要避免使用 $`,你可以一个稍微复杂一些的方法,使用数字变量来显式捕捉匹配内容。以下代码将制表符转换为 4 格空格:
|
你会想为什么这个1 while 循环不直接写成简单的 s///g 的形式,这是因为你需要每次重新计算从行起始的偏移量,而不是从上次匹配的地方开始。
1 while CONDITION 和 while (CONDITION) { } 是等价的,就是更短些。它最早开始出现的时候,当时的 perl 运行第一个比第二个快得多,而到现在,两个都差不多快了。不过前者很方便,而且有些人已经用成了习惯。
标准模块 Text::Tabs 为两种转换都提供了相应的函数,它有一个 $tebstop 变量控制一个制表符对应几个空格,而且它没有引入效率上的问题,因为它使用的是 $1 和 $2,而不是 $& 和$`。
|
也可以用 Text::Tabs 来“扩展”制表符。这个例子使用了默认的 8 做为 $tabstop 的值。
|
Text::Tabs 模块的文档。 perlre(1) 和 perlop(1) 中的 s/// 操作符。 @+ 和 @-(@LAST_MATCH_START and @LAST_MATCH_END)在 Programming Perl 的第二十八章。Programming Perl 的第五章,“When a global substitution just isn't global enough”。
|