如何在 Perl 替换中替换匹配之前的所有文本?

发布于 2024-07-25 11:16:12 字数 406 浏览 4 评论 0原文

我正在读取输入文件 (IN) 的每一行,如果该行以其中一种模式开头,例如“ab”、“cd”、“ef”、“gh”,则将读取的行打印到输出文件 (OUT) ,“ij”等。打印的行的形式为“pattern:100”或“pattern:100:200”。 我需要将“pattern”替换为“myPattern”,即将当前行打印到FILE,但将第一次出现“:”之前的所有文本替换为“myPattern”。 做这个的最好方式是什么?

目前我有:

while ( <IN> )
{ 
    print FILE if /^ab:|^bc:|^ef:|^gh:/;
}

我不确定 substr 替换是否有帮助,因为“模式”可以是“ab”或“cd”或“ef”或“gh”等。

谢谢! 双

I am reading each line of an input file (IN) and printing the line read to an output file (OUT) if the line begins with one of the patterns, say "ab", "cd","ef","gh","ij" etc. The line printed is of form "pattern: 100" or form "pattern: 100:200". I need to replace "pattern" with "myPattern", i.e. print the current line to FILE but replace all the text before the first occurence of ":" with "myPattern". What is the best way to do this?

Currently I have:

while ( <IN> )
{ 
    print FILE if /^ab:|^bc:|^ef:|^gh:/;
}

I am not sure if substr replacement would help as "pattern" can be either "ab" or"cd" or "ef" or "gh" etc.

Thanks!
Bi

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

一笑百媚生 2024-08-01 11:16:13

一般来说,这样做:

my %subst = ( 'ab' => 'newab', 'bc' => 'newbc', 'xy' => 'newxy' );
my $regex = join( '|', map quotemeta, sort { length($b) <=> length($a) } keys %subst );
$regex = qr/^($regex):/;

while ( <IN> ) {
    print FILE if s/$regex/$subst{$1}:/;
}

排序将最长的放在前面,这样如果数据有 ab:: 并且 ab 和 ab: 都被替换,则使用 ab: 代替 ab。

Generically, do this like:

my %subst = ( 'ab' => 'newab', 'bc' => 'newbc', 'xy' => 'newxy' );
my $regex = join( '|', map quotemeta, sort { length($b) <=> length($a) } keys %subst );
$regex = qr/^($regex):/;

while ( <IN> ) {
    print FILE if s/$regex/$subst{$1}:/;
}

The sort puts the longest ones first, so that if the data has ab:: and both ab and ab: are being substituted, ab: is used instead of ab.

杯别 2024-08-01 11:16:13

默认情况下,Perl 的替换运算符 (a) 使用第一个匹配项,(b) 仅替换一个匹配项,(c) 如果进行了替换则返回 true,如果没有则返回 false。

所以:

while ( <IN> )
{ 
    if (s/<pattern1>:/<replace1>/ ||
        s/<pattern2>:/<replace2>/) {
       print FILE;
    }
}

应该为你工作。 请注意,由于短路,只会进行一次替换。

Perl's substitution operator by default (a) uses the first match, (b) only replaces one match and (c) returns true if a replacement was made and false if it wasn't.

So:

while ( <IN> )
{ 
    if (s/<pattern1>:/<replace1>/ ||
        s/<pattern2>:/<replace2>/) {
       print FILE;
    }
}

Should work for you. Note that because of short-circuiting, only one substitution will be made.

樱娆 2024-08-01 11:16:13
sub replacer {

    $line = shift;
    $find = shift;
    $replace = shift;

    $line =~ /([^:]+):/
    if ($1 =~ /$find/) { 
         $line =~ s/([^:]+):/$replace/ ;
         return $line;      
    }
    return ;

}

while (<IN>)
{
    print OUT replacer ($_,"mean","variance");
    print OUT replacer ($_,"pattern","newPattern");
}

我的 Perl 有点生疏,所以语法可能不准确。

编辑:将其放入您的函数中。

sub replacer {

    $line = shift;
    $find = shift;
    $replace = shift;

    $line =~ /([^:]+):/
    if ($1 =~ /$find/) { 
         $line =~ s/([^:]+):/$replace/ ;
         return $line;      
    }
    return ;

}

while (<IN>)
{
    print OUT replacer ($_,"mean","variance");
    print OUT replacer ($_,"pattern","newPattern");
}

My perl is a little rusty, so syntax might not be exact.

edit: Put it in a function for ya.

倾城花音 2024-08-01 11:16:13
while ( <IN> )
{ 
  s/^pattern:/myPattern:/;
  print OUT
}
while ( <IN> )
{ 
  s/^pattern:/myPattern:/;
  print OUT
}
离去的眼神 2024-08-01 11:16:13

这可能就是您想要的:

$expr = "^(ab)|(cd)|(ef)|(gh)|(ij)";
while (<IN>)
{
    if (/$expr:/)
    {
        s/$expr/$myPattern/;
        print FILE;
    }
}

This might be what you want:

$expr = "^(ab)|(cd)|(ef)|(gh)|(ij)";
while (<IN>)
{
    if (/$expr:/)
    {
        s/$expr/$myPattern/;
        print FILE;
    }
}
不再让梦枯萎 2024-08-01 11:16:13

执行上面要求的最短方法是重新使用您的代码,但包括替换。

while ( <IN> )
{ 
    print FILE if s/^(ab|bc|ef|gh):/MyPattern:/;
}

任何左侧图案都将被替换。 如果左侧不匹配,则不会打印任何内容。

The shortest way to do what you ask above is to re-use your code, but include a substitution.

while ( <IN> )
{ 
    print FILE if s/^(ab|bc|ef|gh):/MyPattern:/;
}

Any of the left hand side patterns will be replaced. If the left hand side does not match, nothing will be printed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文