2011-10-04 12 views
4

多くの人が、正規表現では怠惰な量限定子を使わずにできるとしていますが、私はそれらがなければ解決できない問題に遭遇しました(私はここでsedを使用しています)。遅延量指定子を使わずに実際に行うことはできますか?

Iで処理したい文字列は、例えば、ワード・レートによって分離されたストリングで構成されている:

anfhwe9.<<76xnf9247 rate 7dh3_29snpq+074j rate 48jdhsn3gus8 rate 

Iは3つのダッシュで(離れワード「レート」から)、それらのサブストリングを置換します(---)それぞれ。結果は次のようになります:

私が理解しているところ(私はPerlを知らないからです)は、遅延量制限子を使って簡単に行うことができます。 vimには怠惰な量指定子もあります。私は、このコマンド\{-}ができるだけ少ないと一致するようにVimを伝え

:s/.\{-}rate/---rate/g 

を使用してそれをやりました。

しかし、vimはテキストエディタであり、多くのマシンでスクリプトを実行する必要があり、その中にはPerlをインストールしていないものがあります。正規表現に.*[^(rate)]rateのような原子グループと一致しないと言うことができますが、うまくいかなかった場合にも解決できます。

どのようにPOSIX正規表現を使用してこれを達成するためのアイデア、またはそれは不可能ですか?

答えて

2

遅延量子や否定先読み(どちらもPOSIXがサポートしていません)を使用しなければ簡単ではありませんが、これはうまくいくようです。

私は、POSIXの文字クラスを少し難解であると思い出しています。 POSIX準拠でない場合、その正規表現の文字クラスを変更する必要があるかもしれません。このような場合には

+0

@ikegami "レート"の間に少なくとも1文字を必要とする場合は – Asmor

3

、私は(スプリットを使用します):

perl -n -e 'print join ("rate", ("---") x split /rate/)' [input-file] 
+0

正規表現が最良の解決策ではないかもしれないが、彼は特にperlがインストールされていない可能性のある環境を懸念している。 – Asmor

+1

私は確信が持てませんでした - その投稿はperlでタグ付けされています。とにかくsplit(またはtokenize)はほぼすべての言語で実装されており、分割を行うには単純な文字列の一致が必要です。たとえば、Cのstrtokで行うことができます。 –

+0

分割は正規表現をサポートしていますか?どうすれば分別したいのですが、r [aei] teのような正規表現ですか?この場合、分割は機能しません – Gasso

2

は入力にしないことが保証されているすべての文字がありますか?たとえば、 '!' が発生することはできません、あなたはそのユニークなキャラクターを代用するために入力を変換でき、その後、世界的な変換された入力に置き換えるん:

sed 's/ rate /!/g' < input | sed -e 's/[^!]*/---/g' -e 's/!/rate/g' 

別の方法としては、 する類似した方法ではawkのsplitコマンドを使用することです上記のperlの提案は、awkがperlよりも確実に利用可能であると仮定します。 awkの

awk ' 
{ ans="---" 
    n=split($0, x,/rate /); 
    while (n--) { ans = ans "rate---";} 
    print ans 
}' 
0

awk -Frate '{ 
    for (i = 0; ++i <= NF;) 
    $i = (i == 1 || i == NF) && $i == x ? x : "---" 
    }1' OFS=rate infile 
0

あるいは、awk 'BEGIN {OFS=FS="rate"} {for (i=1; i<=NF-1; i++) {$i = "---"}; print}'

1

あなたがストリングの内容を気にしないという事実は、多くのオプションを開きます。たとえば、Bob Liedの提案に追加するには - '!「入力中に発生する可能性があります、あなたが何か他のものにそれを変更することで起動することができます:*私はそれがいつも率で終了することを逃したのだ、私は率非オプション作られ、私も最後に変更

sed -e 's/!/./g' -e 's/rate/!/g' -e 's/[^!]\+/---/g' -e 's/!/rate/g' <input >output 
関連する問題