6

次のような文字列に一致する正規表現を構築しようとしています

1.) $(Something)
2.) $(SomethingElse, ")")
3.) $(SomethingElse, $(SomethingMore), Bla)
4.) $$(NoMatch) <-- should not match
5.) $$$(ShouldMatch) <-- so basically $$ will produce $

テキストで。

EDIT: Something、SomethingElse、NoMatch、ShouldMatchという単語は、他の単語でもかまいません-それらはマクロの名前です。一致させようとする文字列は、テキスト内で発生する可能性がある「マクロ呼び出し」であり、その結果に置き換える必要があります。構文の強調表示のためだけに正規表現が必要です。完全なマクロ呼び出しが強調表示されます。3番は現在あまり輸入されていません。働くためには1番と2番が必要です。4 番と 5 番が上記のように機能しない場合は問題ありませんが$(、a の後に$は一致しません。

現在、私は持っています

(?<!\$)+\$\(([^)]*)\)

構造を適用する別の方法が見つからない場合$(は、先行する がない場合はany に一致します。$$$

私がやりたい次のステップは、閉じ括弧が引用符で囲まれている場合は無視することです。どうすればこれを達成できますか?

編集次のような入力がある場合

Some text, doesn't matter what. And a $(MyMacro, ")") which will be replaced.

完全な'$(MyMacro, ")")'ものが強調表示されます。

すでにこの表現を持っている

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

引用符のエスケープを含む引用符用。しかし、それらの間のすべてを無視する方法でこれを適用する方法がわかりません...

PS .NET を使用して正規表現を適用しています。したがって、バランスの取れたグループがサポートされます。これをすべて適用する方法がわかりません。

4

5 に答える 5

5

次のような式を使用できます。

(?<! \$ )                     # not preceded by $
\$ (?: \$\$ )?                # $ or $$$
\(                            # opening (

(?>                           # non-backtracking atomic group
  (?>                         # non-backtracking atomic group
    [^"'()]+                  # literals, spaces, etc
  | " (?: [^"\\]+ | \\. )* "  # double quoted string with escapes
  | ' (?: [^'\\]+ | \\. )* '  # single quoted string with escapes
  | (?<open>       \( )       # open += 1
  | (?<close-open> \) )       # open -= 1, only if open > 0 (balancing group)
  )*
)

(?(open) (?!) )               # fail if open > 0

\)                            # final )

上記のように引用できます。たとえば、C# の場合:

var regex = new Regex(@"(?x)    # enable eXtended mode (ignore spaces, comments)
(?<! \$ )                       # not preceded by $
\$ (?: \$\$ )                   # $ or $$$
\(                              # opening (

(?>                             # non-backtracking atomic group
  (?>                           # non-backtracking atomic group
    [^""'()]+                   # literals, spaces, etc
  | "" (?: [^""\\]+ | \\. )* "" # double quoted string with escapes
  | '  (?: [^'\\]+ | \\. )*  '  # single quoted string with escapes
  | (?<open>       \( )         # open += 1
  | (?<close-open> \) )         # open -= 1, only if open > 0 (balancing group)
  )*
)

(?(open) (?!) )                 # fail if open > 0

\)                              # final )
");
于 2013-03-13T18:26:15.677 に答える
1

マクロをパラメーターとして使用していない部分(1および2)については、次のことができます。

(?<!\$)+\$\(([^)]*?("[^"]*?")?)+\)

あなたはここでここを見ることができます

マクロ (3) の場合、次のことができます。

(?<!\$)+\$\(([^)]*?("[^"]*?")?(\$\([^)]*?\))?)+\)

ただし、これは括弧付きの文字列を含むマクロでは機能しません。

ここで結果を見ることができます

于 2013-03-11T16:46:29.837 に答える
1

このようなことは複雑なので、次のことを恐れないでください。

正規表現:(?<!\$)(?:\$\$)*(\$\((?:[\w, ]+|(?>"(?:(?<=\\)"|[^"])+")|(?1)+)*\))
ここで説明されたデモ: http://regex101.com/r/yZ5dI7

これはすべての 5 つのポイントに従い、最初の 3 つのマクロ タイプに一致し、接頭辞の数が奇数 "の場合にのみ、複数またはマクロ内マクロのさらに深いバリエーションに一致します。$

于 2013-03-11T20:32:28.937 に答える
0

私は最近、同様の正規表現を探していましたが、正規表現のスキルが悪いため、正規表現よりもC#でテキストを解析する方が速いと判断しました...そのため、Razorコードブロックを削除するためにこのメソッドを書きました。

複雑な正規表現なしで、ニーズに合わせて簡単に変更できます

于 2013-03-06T16:47:00.757 に答える
0

このようなことを意味しますか?

\$\(SomethingElse, \"|[^"\)]?\"\)
于 2013-03-06T16:56:50.713 に答える