特定の単語が前に出ていないすべての単語を使用または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
andを扱う必要はありませんFrank Smith
。Smith
以前に存在しなかったマッチング方法が必要です。John
答え1
これは正規表現が逆に見えるすべての言語で簡単です。もちろん、Perlはリストの最初です。
perl -pe 's/(?<!John\W)Smith/John/g' <<< "John Smith and Jane Johnson talk about Smith's car."
弱点は、「ジョン」と「スミス」の間に単語以外の文字が複数あることです。残念ながら、+
forなどの数量子は、\W
「可変長逆引き参照が実装されていません」というエラーを発生させる可能性があります。
答え2
編集する.. あなたの意見に関して.. これは新しいスクリプトであり(例えば)ウィリアム・スミスには興味がありません。維持するパターンを一時的に難読化します。スミス(絶え間ない)。
sed -r 's/\<(John) (Smith)\>/\1\x01x\2/g;
s/\<Smith\>/John/g; s/\x01x/ /g'
気になるなら先生、奥さん…まあ、これはうまくいきます。
sed -r 's/\<(John|((M(r|rs|s))\.?)) (Smith)\>/\1\x01x\5/g
s/\<Smith\>/John/g; s/\x01x/ /g'
あなたは満足することができますウィリアム彼の名前を次に追加またはたとえば、リストを作成します。
sed -r 's/\<(William|John|...
オリジナルスクリプトです
sed -r 's/(^|[[:punct:]] |\<[a-z]+ )(Smith\>)/\1John/'
答え3
sed -r 's/([^John] )Smith/\1John/g;s/([^Jane] )Johnson/\1Jane/g'
()は姓の前に名前ではなく名前をキャプチャするため、代替時に逆参照されます。
編集する
@manatwork, ザイルズ
あなたは正しいです。どうですか?
sed -r 's/(John Smith)/temp1/g;s/Smith/John/g;s/temp1/John Smith/g'
これがトリックを行うようです。