交换 PERL 字符串中两个相邻单词的更好方法?

问题描述 投票:0回答:2

我遇到过一个奇怪的情况,我在编写的游戏中输入了两个错误的名字。他们互相镜像。例如,亨利·帕特里克和帕特里克·亨利,我想在我编写的错误代码块中交换它们。

现在下面的 PERL 代码就是这样做的,但是临时替换字符串

heinous-hack-string
是一个 hack。有没有更优雅的做事方式?

##################
#nameflip.pl
#
# this flips names where I mistakenly switched first-last and last-first
#

use strict;
use warnings;

my $mystr = "There's this guy named Henry Patrick, and there's another guy named Patrick Henry, " . 
  "and I confused them and need to switch them now!";

print "Before: $mystr\n";

print "After: " . stringNameSwitch($mystr, "Patrick", "Henry") . "\n";

##############################
# awful hack of a subroutine.
#
# what regex would do better?
#
# right now I just want to switch (name1 name2) <=> (name2 name1)

sub stringNameSwitch
{
  my $temp = $_[0];
  $temp =~ s/$_[1] +$_[2]/heinous-hack-string/i;
  $temp =~ s/$_[2] +$_[1]/$_[1] $_[2]/i;
  $temp =~ s/heinous-hack-string/$_[2] $_[1]/i;
  return $temp;
}
regex perl
2个回答
3
投票

也许像这样? 分支重置构造

(?|...)
允许将两个名称捕获到
$1
$2
中,无论它们的出现顺序如何。

use strict;
use warnings 'all';

my $mystr = <<END;
There's this guy named Henry Patrick,
and there's another guy named Patrick Henry,
and I confused them and need to switch them now!
END

print name_switch($mystr, qw/ Henry Patrick /);

sub name_switch {
    my ($s, $n1, $n2) = @_;

    $s =~ s/\b(?|($n1)\s+($n2)|($n2)\s+($n1))\b/$2 $1/gr;
}

输出

There's this guy named Patrick Henry,
and there's another guy named Henry Patrick,
and I confused them and need to switch them now!

0
投票

我认为这是最好的方法。 与在多种语言中切换任意两个变量的方式相同

tmp = a
a = b
b = tmp

所以对于正则表达式......选择一个像“TMP”这样的名称 脚本开关.pl

#!/usr/bin/perl

($n1,$n2) = @ARGV;
@ARGV = ();

while(<>)
{
    # Try to figure this out
    s/\b$n1\b/__TMP__/g;
    s/\b$n2\b/$n1/g;
    s/\b__TMP__\b/$n2/g;
    print;
}

$ echo "   aaa bbb aaa bbb aaa bbb " | ./go.pl aaa bbb
   bbb aaa bbb aaa bbb aaa
© www.soinside.com 2019 - 2024. All rights reserved.