• ベストアンサー

2回以上繰り返される文字列の削除について

以下の文字列(置換前)で、-aaa について複数存在しているので、 最初の -aaa を残して残りの -aaa をすべて削除したいと考えています。 1回の正規表現+置換で行いたいのですが、どのようにいすればよいでしょうか? 【置換前】 -bbb -aaa -ccc -aaa -ddd -eee -aaa -fff 【置換後】 -bbb -aaa -ccc -ddd -eee -fff ちなみに、複数回の正規表現+置換を使ってよい場合は、 while (m/( -aaa.*) -aaa/) { s/( -aaa.*) -aaa/$1/; } でできると考えています。(動作確認まではしていないので間違ってるかも)

質問者が選んだベストアンサー

  • ベストアンサー
  • ryu_chan
  • ベストアンサー率37% (69/186)
回答No.2

「1回の正規表現+置換」という制限がなければ、質問者さんも書いておられるように 1 while s/(-aaa.*) -aaa/$1/; これが分かりやすくていいと思います。 Perl 5.10以上なら、 1 while s/-aaa.*\K -aaa//; という手もありでしょうか。 正規表現だけという条件ならば、以下はいかがでしょうか? s/((^.*?-aaa|\G).*?)( -aaa)?/$1/g; 正規表現はあまり得意でないので、ややこしくしているだけかもしれませんが。 とりあえず、以下の条件はパスしています。 my @strings = ( "-bbb -aaa -ccc -aaa -ddd -eee -aaa -fff", "-bbb -aaa -ccc -ddd -eee -fff", "-aaa -ccc -aaa -ddd -eee -aaa -fff", "-aaa -ccc -ddd -eee -fff", ); for (@strings) { s/((^.*?-aaa|\G).*?)( -aaa)?/$1/g; } use Data::Dumper; print Dumper \@strings;

entree
質問者

お礼

これでできました。ありがとうございました。 s/((^.*?-aaa|\G).*?)( -aaa)?/\1/g;

その他の回答 (1)

  • kumoz
  • ベストアンサー率64% (120/185)
回答No.1

特殊変数の $` (マッチ前部分文字列) を利用すればできると思います。 $str = '-bbb -aaa -ccc -ddd -eee -aaa -fff'; $str =~ s/( -aaa)/$` =~ m| -aaa| ? '' : $1/eg; print "$str\n";

entree
質問者

お礼

これでできました。ありがとうございました。 s/( -aaa)/$` =~ m| -aaa| ? '' : $1/eg;

関連するQ&A