2016-05-19 5 views
2

関数呼び出しのリストをテキストの置き換えに置き換えるには、C#(実際にはtranspiled Razor code)の非常に軽い解析を行う必要があります。関数式の照合と置換

{"Foo.myFunc" : "\"def\"" }を含むセット与えられ、それは、このコード交換する必要がある場合:これで

var res = "abc" + Foo.myFunc(foo, Bar.otherFunc(Baz.funk())); 

var res = "abc" + "def" 

を私は、ネストされた表現を気にしないでください。

これは些細なようで、私はマッピング・セットのすべてのメンバーのためにこのようなものを使用して全体のC#のパーサを構築避けることができるはずだと思う:

  • 表現開始(例えばFoo.myFunc
  • を見つけますPush()/Pop()括弧はStackCount == 0です。式として
  • マークこの式は

を停止しかし、多分私はする必要はありませんまで

  • 式開始からすべてを置き換える停止...そのことができます(おそらく内蔵)の.NETライブラリがあります私のためにこれを行う? REが入っている言語ファミリでは数えられませんが、 C#の正規表現の構文では、何らかの形でバックリファレンスを使って処理できますか?

    編集: this answerへのコメントとしてtrollMe("(")のようなものは、これらのアルゴリズムをオフにスローされますよう、単純にカウントブラケットは、一般的に十分ではありません示しています。真の解析だけで十分ですが、私は推測します(?)。

  • +0

    これは一回限りである場合は、ちょうどNのための正規表現を開始できませんでした、N-1、その後、括弧にマッチした...あなたはそれらすべてを持ってまで? –

    +1

    これは[Roslyn](https://github.com/dotnet/roslyn)ライブラリの仕事のようです。 –

    +0

    @IanMercerおそらく?それを行う方法がわからない... http://www.regular-expressions.info/recurse.html#balancedによると、.NETは再帰的な正規表現をサポートしていないが、適切なものでなければならない "バランスのとれた構造"をサポートしている。私はちょうどそれらを使用する方法を知らない。 – oligofren

    答えて

    2

    通常の文字列のためのトリックは次のようになります。

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

    逐語的文字列:

    (?>@"(""|[^"])*") 
    

    多分これは助けることができますが、私は、これはすべてのケースで動作することをわかりません。

    <func>(?=\()((?>/\*.*?\*/)|(?>@"(""|[^"])*")|(?>"(\\"|[^"])*")|\r?\n|[^()"]|(?<open>\()|(?<-open>\)))+?(?(open)(?!)) 
    

    <func>を関数名に置き換えてください。

    trollMe("\"(", "((", @"abc""de((f")が期待通りに機能しないと言うことは無用です。

    DEMO

    +0

    うわー、それはかなり印象的です。 Roslynのパスを下る前に、私はソースコードと 'RegexOptions.Singleline'フラグの複数のパスを実行するだけでした。場合の95%でOKである必要があります。 – oligofren

    +0

    @oligofrenうまくいかない例がありますか?私は改行を追加できると思います。 –

    +0

    正規表現を改行の処理に変更しました。 –

    関連する問題