如何在 perl 中将 XX1/XXSomething/XX1/Something 之类的模式更改为 XXSomething/XX1/Something

How to change a pattern like XX1/XXSomething/XX1/Something to XXSomething/XX1/Something in perl

我有一个文件,其中有些行有一些模式,例如

M1/XX2/XX1 XX2/XX1/XX2/WCLKB XX2/XX1/XX2/P001  
M1/XX4/XX5 XX4/XX5/XX4/WCLKB XX4/XX5/XX4/P001

XX2 在某些模式中重复出现。我需要将上面的行更改为

M1/XX2/XX1 XX1/XX2/WCLKB XX1/XX2/P001
M1/XX4/XX5 XX5/XX4/WCLKB XX5/XX4/P001

这些 XX 可以改变 XX[0..9] 代码在 Perl 中。

我尝试使用一些正则表达式但感到困惑。

 open(FILE,$FilePath);
 @linesInFile = <FILE>;
 close(FILE);
 foreach $item(@linesInFile){
    if(grep(/^XX?\/XX.\/XX)
  #I dont know how to complete this 
}

根据您在问题描述中的解释 XX[0..9],以下 perl 命令应该可以解决问题:

输入:

$ cat input
M1/XX2/XX1 XX2/XX1/XX2/WCLKB XX2/XX1/XX2/P001  
M1/XX4/XX5 XX4/XX5/XX4/WCLKB XX4/XX5/XX4/P001

命令:

perl -pe 's@\bXX(\d)/XX(\d)/XX@XX/XX@g' input

输出:

M1/XX2/XX1 XX1/XX2/WCLKB XX1/XX2/P001  
M1/XX4/XX5 XX5/XX4/WCLKB XX5/XX4/P001

如果您专门查找 XXn/XXm/XXn/(其中 n 两次都是相同的数字),您可以使用反向引用:

s{(XX[0-9]+/)(XX[0-9]+/)}{}g

此处</code>引用并匹配与第一个捕获组相同的字符串,<code>(XX[0-9]+/).

Live demo:

#!/usr/bin/perl
use strict;
use warnings;

while (my $line = readline DATA) {
    $line =~ s{(XX[0-9]+/)(XX[0-9]+/)}{}g;
    print $line;
}

__DATA__
M1/XX2/XX1 XX2/XX1/XX2/WCLKB XX2/XX1/XX2/P001
M1/XX4/XX5 XX4/XX5/XX4/WCLKB XX4/XX5/XX4/P001

输出:

M1/XX2/XX1 XX1/XX2/WCLKB XX1/XX2/P001
M1/XX4/XX5 XX5/XX4/WCLKB XX5/XX4/P001

如果可以盲目删除第一部分:

while (<>) {
   s{ \K[^\s/]+/}{}g;
   print;
}

作为 one-liner:

perl -pe's{ \K[^\s/]+/}{}g'

如果您想确保它与您指定的模式匹配:

while (<>) {
   s{(?<!\S)(XX\d)/(?=XX[^\s/]+//\S)}{}ag;
   print;
}

作为 one-liner:

perl -pe's{(?<!\S)(XX\d)/(?=XX[^\s/]+//\S)}{}ag'

关键是,意思就是"match what the first capture captured".