如何在 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]+/)
.
#!/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".
我有一个文件,其中有些行有一些模式,例如
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]+/)
.
#!/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".