-3

私は次のURLを持っています:

FILE1.txt

http://www.stackoveflow.com/dog/cat/rabbit/hamster/
192.168.192.168/lion/tiger/elephant/

FILE2.txt

HELLO
GOODBYE

私が達成しようとしている出力:

http://www.stackoveflow.com/dogHELLO/cat/rabbit/hamster/
http://www.stackoveflow.com/dog/catHELLO/rabbit/hamster/
http://www.stackoveflow.com/dog/cat/rabbitHELLO/hamster/
http://www.stackoveflow.com/dog/cat/rabbit/hamsterHELLO/
http://www.stackoveflow.com/dog/cat/rabbit/hamster/HELLO

http://www.stackoveflow.com/dogGOODBYE/cat/rabbit/hamster/
http://www.stackoveflow.com/dog/catGOODBYE/rabbit/hamster/
http://www.stackoveflow.com/dog/cat/rabbitGOODBYE/hamster/
http://www.stackoveflow.com/dog/cat/rabbit/hamsterGOODBYE/
http://www.stackoveflow.com/dog/cat/rabbit/hamster/GOODBYE

192.168.192.168/lionHELLO/tiger/elephant/
192.168.192.168/lion/tigerHELLO/elephant/
192.168.192.168/lion/tiger/elephantHELLO/
192.168.192.168/lion/tiger/elephant/HELLO

192.168.192.168/lionGOODBYE/tiger/elephant/
192.168.192.168/lion/tigerGOODBYE/elephant/
192.168.192.168/lion/tiger/elephantGOODBYE/
192.168.192.168/lion/tiger/elephant/GOODBYE

ご覧のとおり、文字列はすべてのスラッシュの後HELLOGOODBYE挿入されます。スラッシュの後にすでに文字列がある場合は、その後に文字列が追加されますHELLOGOODBYEhttp://www.stackoveflow.com/dogHELLO/cat/rabbit/hamster/など)。

私が試したこと

use strict;
use warnings;

my @f1 = do {
   open my $fh, '<', 'FILE1.txt';
   <$fh>;
};
chomp @f1;

my @f2 = do {
  open my $fh, '<', 'FILE2.txt';
  <$fh>;
};
chomp @f2;

for my $f1 (@f1) {
  my @fields = $f1 =~ m{[^/]+}g;
  for my $f2 (@f2) {
    for my $i (0 .. $#fields) {
      my @new = @fields;
      $new[$i] .= $f2;
      print qq{/$_/\n}, for join '/', @new;
    }
    print "\n\n";
  }
}
#courtesy of Borodin

ただし、このコードは、部分にスラッシュが含まれているURLには対応していません。これは、これらが必要のないときにhttp://置き換えられるためです。http:HELLO/

また、文字列がまだ存在しない場合は、スラッシュを入れたり、スラッシュの後に入れHELLOたりしません。GOODBYEhttp://www.stackoveflow.com/dog/cat/rabbit/hamster/<--SHOULD PUT HELLO AFTER THIS SLASH AS WELL BUT DOSN'T

このコードは、最初から正しい場所に挿入するのHELLOではなく、FILE2.txtの文字列を含むスラッシュを削除してから再挿入するようです。GOODBYE

私の質問

必要な出力を達成するためのより良い方法はありますか、それとも上記の問題に対応するために既存のコードにできることがありますか?

あなたの助けは大いに感謝されます、多くの感謝

4

3 に答える 3

2

散文のアルゴリズムは次のとおりです。

Open File2.txt. Read in all lines, removing the newline. We call the array @words.

Open File2.txt. We call the file handle $fh.

As long as we can read a $line from $fh:

    Remove the newline, remove starting and ending slashes.
    Split the $line at every slash, call the array @animals.

    Loop through the @words, calling each element $word:

        Loop through the indices of the @animals, calling each index $i:

            Make a @copy of the @animals.
            Append the $word to the $i-th element of @copy.
            Join the @copy with slashes, surround it with slashes, and print with newline.

        Print an empty line.
于 2013-02-26T13:04:32.493 に答える
2

このプログラムはあなたが求めることをします。

use strict;
use warnings;
use autodie;

my @f1 = do {
  open my $fh, '<', 'FILE1.txt';
  <$fh>;
};
chomp @f1;

my @f2 = do {
  open my $fh, '<', 'FILE2.txt';
  <$fh>;
};
chomp @f2;

for my $f1 (@f1) {
  my @fields = $f1 =~ m{[^/]+}g;
  for my $f2 (@f2) {
    for my $i (0 .. $#fields) {
      my @new = @fields;
      $new[$i] .= $f2;
      print qq{/$_/\n}, for join '/', @new;
    }
    print "\n\n";
  }
}

出力

/dogHELLO/cat/rabbit/hamster/
/dog/catHELLO/rabbit/hamster/
/dog/cat/rabbitHELLO/hamster/
/dog/cat/rabbit/hamsterHELLO/


/dogGOODBYE/cat/rabbit/hamster/
/dog/catGOODBYE/rabbit/hamster/
/dog/cat/rabbitGOODBYE/hamster/
/dog/cat/rabbit/hamsterGOODBYE/


/lionHELLO/tiger/elephant/
/lion/tigerHELLO/elephant/
/lion/tiger/elephantHELLO/


/lionGOODBYE/tiger/elephant/
/lion/tigerGOODBYE/elephant/
/lion/tiger/elephantGOODBYE/
于 2013-02-26T13:11:49.590 に答える
0

すべてのスラッシュで行を分割するのではなく、正規表現を使用してすべてを行うことができます。

更新版:

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

my @insert_words = qw/HELLO GOODBYE/;
my $word = 0;

while (<DATA>)
{
    chomp;
    foreach my $word (@insert_words)
    {
        my $repeat = 1;
        while ((my $match=$_) =~ s|(?<!/)(?:/(?!/)[^/]*){$repeat}[^/]*\K|$word|)
        {
            print "$match\n";
            $repeat++;
        }
        print "\n";
    }
}

__DATA__
/dog/cat/rabbit/hamster/
http://www.stackoverflow.com/dog/cat/rabbit/hamster/

重要なのは置換演算子です:s|(?<!/)(?:/(?!/)[^/]*){$repeat}[^/]*\K|$word|

(?<!/)(?!/)はそれぞれネガティブルックビハインドとルックアヘッドです。それらは、単一のを一致させるだけであり/、したがってを無視することを保証しhttp://ます。

(?:/(?!/)[^/]*){$repeat}は指定された回数一致する必要があるキャプチャグループであり、一致しなくなるまでその数を増やします。

文字列の最後で一致するという要件を満たすために、[^/]*代わりにを使用する必要がありました。[^/]+そのため、後読みと先読みの両方が必要になります。

\K「この時点までのすべてを一致させますが、一致自体には含めないでください」という意味です。したがって、置換に一致した文字列の先頭全体を含めることを心配する必要はありません。

注:このrオプションは、元の文字列を変更せずに置換を実行する別の方法です。ただし、Perl 5.16が必要です(Amonに感謝)。したがって、例から削除しました。

于 2013-02-26T13:10:41.873 に答える