sed
またはPerl
を使用して、特定の単語の前にない単語をすべて置き換えます。
たとえば、映画のプロットが含まれているテキストファイルがあり、出現するすべてのキャラクターの姓を名に置き換えたいのは、姓が姓の直前にない場合のみです。
サンプルテキストは次のようになります。
John Smith and Jane Johnson talk about Smith's car.
次のようにしたい:
John Smith and Jane Johnson talk about John's car.
sed 's/Smith/John/' file
を実行すると、次のようになります。
John John and Jane Johnson talk about John's car.
姓の前にある名は常に同じになります。 John Smith
とFrank Smith
を処理する必要はありません。前にSmith
がないJohn
に一致する方法が必要です。
正規表現が後ろを見ることができる言語であれば、簡単です。もちろん、Perlはリストの最初です。
Perl -pe 's/(?<!John\W)Smith/John/g' <<< "John Smith and Jane Johnson talk about Smith's car."
弱点は、「John」と「Smith」の間に複数の非Word文字があることです。残念ながら、+
の\W
のような数量詞を使用すると、「可変長の後読みが実装されていません」というエラーが発生します。
[〜#〜] edit [〜#〜] .. re your comment ..これは、(たとえば)William Smithに関係のない新しいスクリプトです。 Smith(変更なし)として保持するパターンを一時的に難読化します。
sed -r 's/\<(John) (Smith)\>/\1\x01x\2/g;
s/\<Smith\>/John/g; s/\x01x/ /g'
Mr。Mrs Mrs ...が気になる場合は、これでうまくいきます。
sed -r 's/\<(John|((M(r|rs|s))\.?)) (Smith)\>/\1\x01x\5/g
s/\<Smith\>/John/g; s/\x01x/ /g'
orリストに彼の名前を追加することで、Williamに対応できます。sed -r 's/\<(William|John|...
これは元のスクリプトです
sed -r 's/(^|[[:punct:]] |\<[a-z]+ )(Smith\>)/\1John/'
sed -r 's/([^John] )Smith/\1John/g;s/([^Jane] )Johnson/\1Jane/g'
()は、LastNameの前に非Firstnameをキャプチャするので、それらは置換で後方参照されます。
編集
@ manatwork、gilles
あなたが正しい。いかがですか
sed -r 's/(John Smith)/temp1/g;s/Smith/John/g;s/temp1/John Smith/g'
これでうまくいくようです。