如何在Perl中跳过剩余部分,类似于awk中的next?

3
在awk中,next命令将会做以下操作:
停止处理当前的输入记录。读取下一个输入记录并从AWK程序中的第一个模式开始重新处理。当到达输入数据的末尾时,执行任何END规则。
假设我的perl脚本是一系列的转换规则,是否有类似的东西可以在perl中模拟它,比如如果我编写以下代码:
s/a/A/g;
s/b/B/g; next();
s/c/C/g;

next?()会检查给定的替换是否成功,然后停止处理剩余的转换规则,并从转换规则的第一个模式重新开始。

示例输入:

R: waltz
M: 3/4
L: 1/4
K: C
|: E2"C"G | d3"G7" | c2"C"G | F3"F" | E2"C"E | EFG | A3"Dm" | G3"G7" |
| E2"C"G | d3"G7" | c2"C"G | F3"F" | E2"C"G | G"G7"AB | c3"C"- | c3 ||
||d"G7" z/G/ G | BAG | E2"C"G | c3 | A2"F"c | d2"D"c | B3"G" | G3 |
| E2"C"G | d3"G7" | c2"C"G | F3"F" | E2"C"G | G"G7"AB c3"C" | c3 :|

ABC音符,如E2Gd3等,是在一个while /re/gi循环中最后处理/替换的,而吉他和弦"C" "Dm" "G7"等则是先替换,然后跳过ABC音符的替换。 我尝试使用next if s/".*?"/^$&/g;来替换吉他和弦部分,但是,所有的ABC音符替换都被跳过了,后面的while循环无法执行到。

1
听起来好像你想要的是 next if s/foo/bar/g - 一个确切的输入/输出示例会有助于澄清。 - undefined
啊,我忘了@jqurious这种语法,现在在原始帖子中提供了示例输入,而输出被跳过了。只要记住一切都要被替换。关于“如何替换”的部分与这个问题无关。 - undefined
你能提供预期的输出吗? - undefined
我意识到我提出的问题和我给出的示例输入与问题本身不同,因此预期的输出现在是无关紧要的,我将把你对我简单问题的简单回答作为答案。谢谢。 - undefined
3个回答

4
我作为一个一行代码会做什么:
perl -lnE 's/a/A/g; next if s/b/B/g; s/c/C/g; say' file

1
这将跳过偶数并打印奇数。
#!/usr/bin/perl
use v5.30;
use warnings;

my @numbers = 1..20;

for my $number (@numbers){
    next if $number % 2 == 0;
    say $number;
}

1
下面是官方文件链接:https://perldoc.perl.org/functions/next - undefined

1
我不是Perl大师,但如果你有某种语言的可行解决方案,并想将其转换为另一种语言,你可以找到相应的转译器。我成功找到了a2p,并通过执行sudo cpanm -S App::a2p命令来获取它,然后我根据你的示例创建了program.awk文件。
{gsub(/a/,"A")}
gsub(/b/,"B"){next}
{gsub(/c/,"C")}
{print}

作为gsub函数,返回替换的次数。

当使用作为模式时,它将与询问是否进行了任何替换相同。请注意,它将不会打印具有b的行,因为GNU AWK指示在print之前next到下一行。然后我以以下方式调用a2p

a2p program.awk > program.pl

program.pl的内容是

#!/usr/bin/perl
eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
    if $running_under_some_shell;
            # this emulates #! processing on NIH machines.
            # (remove #! line above if indigestible)

eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_0-9]+=)(.*)/ && shift;
            # process any FOO=bar switches

$, = ' ';       # set output field separator
$\ = "\n";      # set output record separator

line: while (<>) {
    chomp;  # strip record separator
    s/a/A/g;
    if (s/b/B/g) {
    next line;
    }
    s/c/C/g;
    print $_;
}

我使用 file.txt 进行了测试,其内容如下。
aaa
aab
aac
aba
abb
abc
aca
acb
acc
baa
bab
bac
bba
bbb
bbc
bca
bcb
bcc
caa
cab
cac
cba
cbb
cbc
cca
ccb
ccc

通过做
perl program.pl file.txt

并获得预期的输出,即。
AAA
AAC
ACA
ACC
CAA
CAC
CCA
CCC

(使用Perl 5版本34,子版本0进行测试)

谢谢,+1。我学到了我可以使用if (s/b/B/g) - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接