0

GNU sedバージョン4.2.1を使用していて、他の2つの文字列で区切られた文字列を抽出するために貪欲でないSED正規表現を作成しようとしています。区切り文字列が1文字の場合、これは簡単です。

s:{\([^}]*\)}:\1:g

この例では、文字列は左側が「{」、右側が「}」で区切られています。

区切り文字列が複数の文字である場合、たとえば「{{{」および「}}}」と言います。上記の式を次のように調整できます。

s:{{{\([^}}}]*\)}}}:\1:g

したがって、中央の式は、「}}}」の終了文字列を含まないものと一致します。ただし、これは、一致文字列に「}」がまったく含まれていない場合にのみ機能します。何かのようなもの:

{{{cannot match {this broken} example}}}

動作しませんが

{{{can match this example}}}

動作します。もちろん

s:{{{\(.*\)}}}:\1:g

常に機能しますが、貪欲なので、同じ行に複数のパターンが発生する場合には適していません。

私は、それ以外のことを意味し、[^a]それ以外aのことを意味することを理解していますが、それは機能しているように見えますが、3つの連続する文字のシーケンスを除外する正しい方法ではないと思います。[^ab]ab[^}}}]

では、他の2つの文字列で区切られた文字列に一致するSEDの正規表現を作成するにはどうすればよいですか?

4

2 に答える 2

1

[^}}}]うまくいかないのは正しいです。否定された文字クラスは、その中の文字以外のすべてのものに一致します。文字を繰り返してもロジックは変わりません。だからあなたが書いたものは と同じ[^}]です。(式の中に中括弧がない場合にこれが機能する理由は簡単にわかります)。

?Perl および互換性のある正規表現では、 a*または+non-greedyを作成するために使用できます。

 s:{{{(.*?)}}}:$1:g

これは常に}}}、開始後最初に一致し{{{ます。

ただし、これは Sed では不可能です。実際、セドがこの試合を行う方法はないと思います。これを行う唯一の他の方法は、先読みなどの高度な機能を使用することですが、これは Sed にもありません。

オプションを使用して sed のような方法で Perl を簡単に使用でき-peます。これにより、Perl はコマンド ラインから 1 行のコードを取得し ( -e)、各行を自動的にループして結果を出力します ( -p)。

perl -pe 's:{{{(.*?)}}}:$1:g'

ファイルの-iインプレース編集オプションも便利ですが、最初に正規表現が正しいことを確認してください!

詳細については、perlrunを参照してください。

于 2013-03-05T12:17:30.340 に答える
0

あなたsedは次のようなことができます:

sed -e :a -e 's/\(.*\){{{\(.*\)}}}/\1\2/ ; ta'

と:

{{{can match this example}}} {{{can match this 2nd example}}}

これは与える:

can match this example can match this 2nd example

怠惰なマッチングではありませんが、右から左に置き換えることで、sed の貪欲さを生かすことができます。

于 2013-03-05T14:26:26.617 に答える