2016-08-05 4 views
1

コンテンツを格納する複数のスカラー変数を検索して置換したい(内容は各文字列ごとに異なる)2つの行を挿入して両方の変数。シングルショット内の両方の変数の同じ文字の検索と置換

交換するすべての文字列が1つのショットで同時に置換される可能性はありますか?内容は文字列で異なることに注意してください。 (私の方法は質問ですが子供ですが、私はコードラインを減らそうとしていますが、200行以上の置換えをしています)

+1

なぜサブを使用しないのですか? – Toto

+0

@Toto:私がサブを使用している場合、私たちは交換のための回線を減らすことはできますか?はいの場合は、解決する方法を詳細に要求しています。 – ssr1012

+0

http://search.cpan.org/dist/HTML-Parser/lib/HTML/Entities.pm – mwp

答えて

7

forのループに変数を入れることができます。これらの変数はそれぞれ$_順番に。どちらもアンダースコアやセミコロンは正規表現パターン

for ($str1, $str2) { 
    s/_/&underscore;/g; 
    s/\^/&carrot;/g; 
} 

の内側にエスケープする必要があることに注意してくださいしかし、それらの両方が非標準のエンティティです。あなたは自分でそれを宣言しましたか?そして野菜であるcarrotではなく、おそらくcaretを意味します。私はそれが^と呼ばれるのを見ましたが、私はそれも非標準だと思います。おそらく^(アンダースコアの場合は_)を使用することができます。

+0

優れた答え。 (エンティティ名も変更します) – ssr1012

2

おそらく最も簡単な方法は、マッピングルールを定義し、それらのルールから正規表現を作成し、それを適用するための提供関数です。ここではそれで刺します:

my %map = (
    "_" => "&underscore;", 
    "^" => "⁁", 
); 

sub apply_map { 
    $_[0] =~ s/(${\ 
    join "|", map quotemeta, keys %map 
    })/$map{$1}/g; 
} 

apply_map $str1; 
apply_map $str2; 

そして、少数の文で複数の文字列にマップを適用するにはボロディンの答えを借りる:

foreach ($str1, $str1) { 
    apply_map $_; 
} 

あるいは、複数の引数を取るようにapply_mapを変更します。

sub apply_map { 
    s/(${\ 
    join "|", map quotemeta, keys %map 
    })/$map{$1}/g foreach @_; 
} 

apply_map $str1, $str2; 

quotemetaに注意してください。これにより、マップキー内の特殊文字が正規表現の動作に影響しないようにします。私はs///の式を補間するために${\ .. }の構文も使用していますが、別のパターン文字列を作成する方が明確かもしれません。置換対象の文字がすべて1文字の場合は、''に参加し、|に参加する代わりに文字クラス([_^]など)を使用できます。

関連する問題