2009-06-01 4 views
3

私はPerlの正規表現を使って検索と置換をしようとしています。Perlでの検索と置換の際にテキストを置き換える代わりに、どのように追加できますか?

私が探していたテキストは、次のとおりです。

<space>Number<space>NumberNumberNumber 

と私はそれを交換したい:

<space>Number<space>NumberNumberNumberI 

私は、文字列を見つけることで動作し、次の正規表現があります。

\s[0-9]\s[0-9[0-9][0-9] 

文字列の置換についてはどうすればよいですか?基本的には、私は最後に「私」を追加したいだけです。

私が使用しています:

perl -pi -e "s/\s[0-9]\s[0-9][0-9][0-9]/I/;" testFile 

が、これは私に全部を交換するのではなく、それに追加されています。

答えて

9

これは、後方参照のためのものです。キャプチャしたいテキストのセクションをカッコで囲むだけです。最初の括弧は$ 1で、二番目の括弧は$ 2で、などとなります。 5.10で

s/(\s[0-9]\s[0-9]{3})/$1I/ 

あなたは<>挟ん

s/(?<bodytext>\s[0-9]\s[0-9]{3})/$+{bodytext}I/ 

ものは名前であると言うことができますので、私たちは、named capturesを得ました。名前は%+変数のキーになり、値はキャプチャされたテキストです。

別の解決策は、あなたがDOUBを使用している場合

perl -pi -e 's/(\s[0-9]\s[0-9][0-9][0-9])/$1I/' filename 

を試してみてください\K

s/\s[0-9]\s[0-9]{3}\K/I/ 

速記、5.10に新しい、zero-width positive look-behinds

s/(?<=\s[0-9]\s[0-9]{3})/I/ 

またはそのを使用することですPerlがそれを見る前に$ 1がシェルによって補間されています。あなたがうまくいくと思われるものに問題がある場合は、Perlが見ているものを見てみることをお勧めします。これを行うにはB::Deparse

これは次の出力を生成します。

BEGIN { $^I = ""; } 
LINE: while (defined($_ = <ARGV>)) { 
    s/(\s[0-9]\s[0-9][0-9][0-9])/I/; 
} 
continue { 
    print $_; 
} 
-e syntax OK 

これより、$1が見つからないことがわかります。単一引用符で再び試すことができます:

perl -MO=Deparse -pi -e 's/(\s[0-9]\s[0-9][0-9][0-9])/$1I/' filename 
BEGIN { $^I = ""; } 
LINE: while (defined($_ = <ARGV>)) { 
    s/(\s[0-9]\s[0-9][0-9][0-9])/$1I/; 
} 
continue { 
    print $_; 
} 
-e syntax OK 

、一度に脱出して:

perl -MO=Deparse -pi -e "s/(\s[0-9]\s[0-9][0-9][0-9])/\$1I/" filename 
BEGIN { $^I = ""; } 
LINE: while (defined($_ = <ARGV>)) { 
    s/(\s[0-9]\s[0-9][0-9][0-9])/$1I/; 
} 
continue { 
    print $_; 
} 
-e syntax OK 
+0

ですまだ全部私と交換しています:( –

+0

括弧を追加しましたか? –

+0

これは私の完全なコマンドです。perl -pi -e "s /(\ s [0-9] \ s [0-9] [0-9] [0-9])/ $ 1I /" testFile.phy –

0

2009からの回答の短いバージョンは - あなたが使用することができますゼロ幅の正の後読みアサーション(?<=pattern) 、または\K、一致後に何かを挿入する:

%echo "test" | perl -p -e "s/(?<=test)/ing/" 
testing 
%echo "test" | perl -p -e "s/test\K/ing/" 
testing 
% 

また、あなたの試合の前に何かを挿入するために、あなたはゼロ幅の正の先読みアサーション(?=pattern)使用したい:

%echo "test" | perl -p -e "s/(?=test)/#/" 
#test 
% 

参考: