2

次のようなパターンがあります: substring1(substring2),(xxxx)xxxx Need substring1(最初の括弧の前の文字列)とsubstring2(最初の括弧内の文字列)は問題ありません。また、1つの部分文字列の最初の括弧の後にすべての文字が必要です。これらは括弧自体である可能性があります。したがって、パターンを使用します-regexp {(.*?)\((.*?)\)(.*)} $a match sub1 sub2 sub3 しかし、最後の部分文字列はで収集できませんsub3。私を助けてください!

> 247 % set a substring1(substring2),(xxxx)xxxx
> 248 % regexp {(.*?)\((.*?)\)(.*)} $a match sub1 sub2 sub3 1
> 249 % puts $sub1; puts $sub2; puts $sub3 
substring1
substring2

> 250 % 
4

2 に答える 2

4

あなたが抱えている問題は、TclのREエンジンが自動理論であり、貪欲モードの切り替えにうまく対応できないことです。特に、最初の概算では、文字列の最初の数量詞がRE全体の貪欲さを設定する場合があります。(実際にはそうではありませんが、切り替えるタイミングのルールは非常に難解です。)

ネストされた括弧がない場合は、次のように使用できます。

regexp {^([^()]*)\(([^()]*)\)(.*)$} $a match sub1 sub2 sub3

テスト(明らかなビットは省略):

% puts $sub1|$sub2|$sub3
substring1|substring2|,(xxxx)xxxx

ネストされた括弧の処理ははるかに困難です。問題は、任意のネストが、有限オートマトンによって正式に一致する可能性のある「言語」を処理しなくなることです(代わりに、異なる決定可能性クラスであるプッシュダウンオートマトンが必要です)。ネストのレベルを制限するために、それをエンコードできます。1つのレベルでそれを行う方法は次のとおりです。

regexp {^([^(]*)\(((?:[^()]|\([^()]*\))*)\)(.*)$} $a match sub1 sub2 sub3

つまり、に置き換え[^()]ました(?:[^()]|\([^()]*\))[^()]2番目のサブを必要なだけ再度置き換えることで、簡単に深く掘り下げることができます。ただし、これによりREがより複雑になります(これは実際には問題です。任意のネストされたパレンマッチャーには、無限に長いREが必要になります)。その特定の問題に対処している場合は、他の手法を探す方が簡単です(たとえば、),コンマを使用したり、再帰的なパーサーを使用したりするなど、一致する長い「チャンクの終わり」の文字列)。

于 2012-08-02T09:52:04.143 に答える
1

終了変数'$'まで一致して終了する必要があります

 () 27 % regexp {(.*?)\((.*?)\)(.*).*$} $a match sub1 sub2 sub3
 1
 () 28 % set sub3
 ,(xxxx)xxxx
 () 29 % set sub1
 substring1
 () 30 % set sub2
 substring2
 () 31 % set sub3
 ,(xxxx)xxxx
于 2016-01-27T08:32:27.720 に答える