4

次のhtmlテキスト(巨大なファイルの抜粋)の一部を置き換えて、古いフォーラム形式(2年前に行われた非常に悪いフォーラム移植作業の結果)を通常のphpBB形式に更新したいと思います。

    <blockquote id="quote"><font size="1" face="Verdana, Arial, Helvetica" id="quote">quote:<hr height="1" noshade id="quote"><i>written by User</i>

これは次のようにフィルタリングする必要があります。

    [quote=User]

sedで次の正規表現を使用しました

    s/<blockquote.*written by \(.*\)<\/i>/[quote=\1]/g

これは特定の例で機能しますが、実際のファイルでは、このような複数の引用符を1行に含めることができます。その場合、sedは貪欲すぎて、最初の一致と最後の一致の間のすべてを[quote=...]タグに配置します。行内のこのパターンのすべての出現を置き換えるように見えることはできません...(ネストされた引用符はないと思いますが、それはさらに困難になります)

4

3 に答える 3

3

Perl互換の正規表現を使用するバージョンのsed(1)が必要です。これにより、最小限の一致を作成したり、先読みが負のバージョンを作成したりできます。

これを行う最も簡単な方法は、最初にPerlを使用することです。

既存のsedスクリプトがある場合は、 s2p(1)ユーティリティを使用してPerlに変換できます。Perlでは、演算子$1の右側で実際に使用したいことに注意してください。s///ほとんどの場合、\1は適用除外ですが、一般的には、次のよう$1にします。

s/<blockquote.*?written by (.*?)<\/i>/[quote=$1]/g;

パーレンの前面からバックスラッシュを削除したことに注意してください。Perlを使用するもう1つの利点は、(awkのような)正気のegrepスタイルの正規表現使用することです。

Perlを使用するもう1つの利点は、ペアのネスト可能な区切り文字を使用して、醜い円記号を回避できることです。例えば:

s{<blockquote.*?written by (.*?)</i>}
 {[quote=$1]}g;

その他の利点としては、PerlがUTF-8(現在はWebの多数派のエンコード形式)とうまく調和していることや、 sedが必要とする極端な苦痛なしに複数行の一致を実行できることが挙げられます。例えば:

$ perl -CSD -00 -pe 's{<blockquote.*?written by (.*?)</i>}{[quote=$1]}gs' file1.utf8 file2.utf8 ...

-CSD、stdin、stdout、およびファイルをUTF-8として処理します。は-00、ファイル全体を1つのフォールスラップで読み取るようにし、/s必要に応じてドットが改行の境界を越えるようにします。

于 2012-06-09T21:03:19.250 に答える
1

sed欲張りでないマッチをサポートしているとは思いません。あなたはperlを試すことができます:

perl -pe 's/<blockquote.*?written by \(.*\)<\/i>/[quote=\1]/g' filename
于 2012-06-09T20:50:46.007 に答える
0

これはあなたのために働くかもしれません:

sed '/<blockquote.*written by .*<\/i>/!b;s/<blockquote/\n/g;s/\n[^\n]*written by \([^\n]*\)<\/i>/[quote=\1]/g;s/\n/\<blockquote/g' file

説明:

  • 行にパターンが含まれていない場合は、スキップしてください。/<blockquote.*written by .*<\/i>/!b
  • パターンの前面を、行全体でグローバルに改行に変更します。s/<blockquote/\n/g
  • [^\n]*の代わりにを使用して、改行の後に残りのパターンをグローバルに置き換えます.*s/\n[^\n]*written by \([^\n]*\)<\/i>/[quote=\1]/g
  • 元のフロントパターンに変更されていない改行を元に戻します。s/\n/\<blockquote/g
于 2012-06-09T21:41:11.357 に答える