我想用一个标签替换每行开头的每两个空格。 我尝试了以下方法:
s/^(\s{2})+/\t/gm;
它没有用。
答案 0 :(得分:5)
如果您逐行阅读文件:
$line =~ s/\G[ ]{2}/\t/g;
如果你诋毁了整个文件:
$file =~ s/(?:\G|^)[ ]{2}/\t/mg;
答案 1 :(得分:2)
this怎么样?
my $test_string = " some test stuff\ndivided to\n provide the challenge";
$test_string =~ s/^[ ]{2}/\t/gm;
print $test_string;
说明:\s
实际上不是单个符号别名,而是字符“空白”类:例如,它包括\n\
和\t
。如果您只想替换空格,请在正则表达式中使用空格;为我设置一个字符类(而不仅仅是/^ {2}/...
更具可读性(并且不会因/x
modifier而中断。)
此外,如果您只想替换两个空格符号,则无需使用+
量词。
更新:如果您需要替换每个两个空格,我想我会改用它:
$test_string =~ s#^((?:[ ]{2})+)#"\t" x (length($1)/2)#gme;
...或者只是\ G锚在ikegami的回答中。
答案 2 :(得分:2)
请记住,+
量词表示“一个或多个”,并且它适用于\s{2}
,这意味着“正好有两个空白字符。”对于一个简单的示例,请考虑一个创建字符串的程序零到十个空格并尝试将它们与类似的模式匹配。
#! /usr/bin/env perl
use strict;
use warnings;
for (0 .. 10) {
$_ = " " x $_;
printf "%-13s %s\n", "[$_]:", /^(\s{2})+$/ ? "match!" : "no match.";
}
输出:
[]: no match. [ ]: no match. [ ]: match! [ ]: no match. [ ]: match! [ ]: no match. [ ]: match! [ ]: no match. [ ]: match! [ ]: no match. [ ]: match!
如上所述,您的模式将单个TAB字符替换为逻辑行首的任何正偶数空白字符。
您没有提供更广泛的代码上下文。通过使用/m
和/g
开关,我假设您有一些文本块,可能是文件的整个内容,您希望作为一个整体进行操作。下面的程序使用here-document模拟这种假设情况,并用TAB替换每行的前两个空格。
#! /usr/bin/env perl
use strict;
use warnings;
$_ = <<EOText;
Three
Two
Four
Five
Zero
One
EOText
s/^ /\t/mg;
# for display purposes only
s/\t/\\t/g;
print;
输出:
\t Three \tTwo \t Four \t Five Zero One
请注意,额外评论s///
不会保留在您的代码中。它可以在空格和TAB字符之间添加对比度。
如果这是您的计划的唯一目的,它将成为一个简单的单行。要使用修改后的内容创建新文件,请使用
$ perl -pe 's/^ /\t/' input-file >output-file
就地编辑看起来像
$ perl -i.bak -pe 's/^ /\t/' input-file
答案 3 :(得分:1)
作为替代解决方案,如果没有/m
修饰符,您可以使用正向lookbehind。这种方法对于需要检查其他内容的情况非常有用,而不仅仅是行首,因此当\m
修饰符不起作用时>&gt;
$_ = " 123\n 456\n 789";
s/(?:(?<=^)|(?<=\n))\s{2}/\t/g;
print $_;
在上面的示例代码中,位于字符串/g
或\s{2}
新行字符(?<=^)
后面的每个(?: .. | .. )
双空白(?<=\n)
被替换为制表符\t
。