perl模式匹配从行尾

时间:2017-05-30 08:39:14

标签: regex perl regex-greedy

我试图在我遇到的每一行的末尾删除评论。但是,如果除了结尾之外在最开始时进行评论,我有兴趣保留该行。

例如:

output port_a; // comments remove this port

如果我使用此正则表达式$line =~ s/\/{2,}.*?$//;,则会正确删除注释,只会产生我想用于进一步处理的模式,即:

output port_a;

但是,可能会在开头注释一行:

// output port_a; // comments remove this port

在这种情况下,我想在行的开头保留注释,但删除该行末尾的注释。

// output port_a; 

使用相同的正则表达式$line =~ s/\/{2,}.*?$//;会删除所有内容!

我尝试使用s/\/{2,}[^\/]+$//g,但这并没有删除包含斜杠的评论,这是不正确的:

// output port_a; // comments read/write    

4 个答案:

答案 0 :(得分:0)

以下工作,使用@作为正则表达式分隔符而不是/以避免/之前的反斜杠并更清晰

s@//([^/]|/([^/]|$))*$@@

工作原理。 在//之后:我们可以找到

  • [^/](除/之外的任何字符)
  • /后跟[^/]$行结束

答案 1 :(得分:0)

使用钢化点

$line =~ s/\/{2,}(?:(?!\/\/).)*?$//;

Regex101 Demo

正则表达式:\/{2,}(?:(?!\/\/).)*?$

  • \/{2,}匹配2个或更多斜杠(表示评论开头)
  • (?:(?!\/\/).)*?表示一个淬火点(表示除了//之前的任何字符)。这是使用否定前瞻(?!\/\/)指定的。
  • $结束主播

希望这有帮助!

答案 2 :(得分:0)

在开头允许选项/,如果

,则删除尾随注释
s|^\s*/?.+?\K//.*||g;

需要+量词而不是*,以便不匹配具有唯一注释的行。

\Klookbehind的一种形式,零宽度断言,它之前的模式确实存在(它不消耗任何东西)。它还丢弃了之前的所有匹配项,因此我们不必捕获它们并将它们重新放入。这也允许\K处理可变长度模式。

使用显示的示例进行测试

use warnings;
use strict;
use feature 'say';

my @tests = (
    'output port_a; // comments remove this port',
    '// output port_a; // comments remove this port',
    '// output port_a; // comments read/write'
);

for (@tests)
{ 
    s|^\s*/?.+?\K//.*||gx;
    say;
}

输出

output port_a; 
// output port_a;
// output port_a;

答案 3 :(得分:0)

这会删除该行上的最后注释。它更清楚

s|.*\K//.*||

这是一个演示程序

use strict;
use warnings 'all';

while ( <DATA> ) {

    print "$.\n";

    print;

    s|.*\K//.*||;
    print;

    print "\n";
}

__DATA__
output port_a; // comments remove this port
output port_a;
// output port_a; // comments remove this port
// output port_a; 

输出

1
output port_a; // comments remove this port
output port_a; 

2
output port_a;
output port_a;

3
// output port_a; // comments remove this port
// output port_a; 

4
// output port_a;