2

私は RegEx について少し知識がありますが、現時点では私の能力をはるかに超えています。

一致する閉じ括弧を持たない最後の開き括弧の前のテキストを見つけるのに助けが必要です。

(開発中のオープンソースソフトウェアのCallTip用です。)

以下にいくつかの例を示します。

--------------------------
Text               I need
--------------------------
aaa(                  aaa
aaa(x)                ''
aaa(bbb(              bbb
aaa(y=bbb(            bbb
aaa(y=bbb()           aaa
aaa(y <- bbb()        aaa
aaa(bbb(x)            aaa
aaa(bbb(ccc(          ccc
aaa(bbb(x), ccc(      ccc
aaa(bbb(x), ccc()     aaa
aaa(bbb(x), ccc())    ''
--------------------------

これらの状況で RegEx (PCRE) を作成することは可能ですか?

私が得た最高のものでし\([^\(]+$たが、それは良くなく、私が必要としているものとは正反対です.

誰でも助けてくれますか?

4

4 に答える 4

3

ここに画像の説明を入力

この JavaScript 関数を見てください。

var recreg = function(x) {
var r = /[a-zA-Z]+\([^()]*\)/;
while(x.match(r)) x = x.replace(r,'');
return x
}

これを適用すると、閉じ括弧のない一致しない部分がすべて残り、最後のアルファベットの単語だけが必要になります。

var lastpart = function(y) { return y.match(/([a-zA-Z]+)\([^(]*$/); }}

アイデアは、それを次のように使用することです

 lastpart(recreg('aaa(y <- bbb()'))

次に、結果が null かどうかを確認するか、一致するグループを取得しますresult[1]?Rほとんどの正規表現エンジンは、再帰的な正規表現マッチングに必要なフラグをサポートしていません。

これは、再帰的な正規表現をシミュレートした JavaScript 表現のサンプルであることに注意してください。http://www.catonmat.net/blog/recursive-regular-expressions/を読む

于 2013-06-06T04:28:58.670 に答える
1

これは、すべてのサンプル文字列で正しく機能します。

\w+(?=\((?:[^()]*\([^()]*\))*[^()]*$)

最も興味深い部分は次のとおりです。

(?:[^()]*\([^()]*\))*

ゼロ個以上のバランスの取れた括弧のペアと、それらの前および間の非括弧文字 (サンプル文字列のy=bbb()and など) に一致します。bbb(x), ccc()その部分が完了すると、最終的[^()]*$に、文字列の末尾の前に括弧がないことが保証されます。

ただし、この正規表現は、入れ子のレベルが 1 つしかないという前提に基づいていることに注意してください。つまり、これらが有効であると想定しています。

aaa()
aaa(bbb())
aaa(bbb(), ccc())

...しかし、これはそうではありません:

aaa(bbb(ccc()))

サンプルの文字列ccc(bbb(aaa(は、マルチレベルのネストが実際に許可されていることを暗示しているようです。その場合、正規表現だけでは問題を解決できません。(確かに、いくつかの正規表現フレーバーは再帰パターンをサポートしていますが、構文は正規表現の標準から見ても恐ろしいものです。自分の正規表現を書いてから 1 週間後には読めなくなることを保証します。)

于 2013-06-06T04:58:31.770 に答える
0

これに使用している正規表現言語/プラットフォームがわからず、プラットフォームでサブパターンが許可されているかどうかもわかりません。ただし、次の 2 ステップの PHP コードは、上記のすべてのケースで機能します。

$str = 'aaa(bbb(x), ccc()'; // your original string

// find and replace all balanced square brackets with blank
$repl = preg_replace('/ ( \( (?: [^()]* | (?1) )* \) ) /x', '', $str);

$matched = '';
// find word just before opening square bracket in replaced string
if (preg_match('/\w+(?=[^\w(]*\([^(]*$)/', $repl, $arr))
   $matched = $arr[0];
echo "*** Matched: [$matched]\n";

ライブデモ: http://ideone.com/evXQYt

于 2013-06-06T04:29:09.057 に答える
0

部分的な解決策 - これは、正規表現がループ可能なプログラミング言語内から呼び出されることを前提としています。

1)入力を刈り込みます: 一致する括弧を見つけ、間にあるものをすべて削除します。一致がなくなるまで続けます。([^()])正規表現は、括弧ではなく開き括弧、閉じ括弧を探します。「検索して何も置換しない」ループの一部である必要があります。これは「内側から」トリミングします。

2) 剪定後、括弧が残っていないか、先頭/末尾の括弧のみが残っています。ここで、開き括弧の直前の単語を見つける必要があります。これには のような正規表現が必要\w(です。ただし、閉じていない括弧が複数ある場合は機能しません。最後の 1 つを取得するには、貪欲な一致 (最後の をグループ化\w)^.*\w(を使用できます。

「おおよその」解決策と言っているのは、使用している環境によって、「この一致するグループ」の言い方や、前にバックスラッシュを付ける必要があるかどうかが()異なるためです。iPhoneで確認するのは難しいので、その詳細は省略しました。

これにより、あなたや他の人が完全な解決策を思いつくようになることを願っています.

于 2013-06-06T03:14:47.200 に答える