Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 函数表达式的匹配与替换_C#_Regex_Parsing_Backreference - Fatal编程技术网

C# 函数表达式的匹配与替换

C# 函数表达式的匹配与替换,c#,regex,parsing,backreference,C#,Regex,Parsing,Backreference,我需要对C#(实际上)进行一些非常简单的解析,用文本替换来替换函数调用列表 如果给定一个包含{“Foo.myFunc”:“\“def\”}的集合,则应替换此代码: var res = "abc" + Foo.myFunc(foo, Bar.otherFunc( Baz.funk())); 为此: var res = "abc" + "def" 我不关心嵌套表达式 这看起来相当简单,我认为我应该能够避免为映射集的每个成员使用这样的东西来构建整个C#解析器: 查找表达式开始(例如Foo.myF

我需要对C#(实际上)进行一些非常简单的解析,用文本替换来替换函数调用列表

如果给定一个包含
{“Foo.myFunc”:“\“def\”}
的集合,则应替换此代码:

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

var res = "abc" + "def"
我不关心嵌套表达式

这看起来相当简单,我认为我应该能够避免为映射集的每个成员使用这样的东西来构建整个C#解析器:

  • 查找表达式开始(例如
    Foo.myFunc
  • Push()
    /
    Pop()
    堆栈上的括号直到
    Count==0
  • 将此标记为表达式停止
  • 替换从表达式开始到表达式停止的所有内容
但也许我不需要。。。是否有一个(可能是内置的).NET库可以为我这样做?在RE所在的语言家族中,计数是不可能的,但也许C#中的扩展正则表达式语法可以通过反向引用以某种方式处理这个问题

编辑:
正如注释所示,简单地计算括号通常是不够的,因为像
trollMe(“(”
)这样的东西会抛弃这些算法。我想只有真正的解析才足够(?)。

普通字符串的技巧是:

(?>"(\\"|[^"])*")
逐字记录字符串:

(?>@"(""|[^"])*")
也许这会有所帮助,但我不确定这是否在所有情况下都有效:

<func>(?=\()((?>/\*.*?\*/)|(?>@"(""|[^"])*")|(?>"(\\"|[^"])*")|\r?\n|[^()"]|(?<open>\()|(?<-open>\)))+?(?(open)(?!))
(?=\()((?>/\****?*/)|(?>“(?”[^“])*”)(?>“(\ \”[^“])*”)\r?\n[^()”]|(?\()(?)+(?)+(?(开放式)(?!)
用函数名替换

说trollMe(\”(“,”((“,@“abc”)de((f))工作正常是没有用的


如果这是一次性的,你能不能先用一个正则表达式来表示N个匹配的圆括号,然后是N-1,…直到你把它们都弄到手?这听起来像是库的工作。@IanMercer可能吗?不知道怎么做…根据.NET不支持递归正则表达式,但它支持“平衡结构”"这应该很合适。我只是不知道如何使用它们。@RaymondChen这绝对是一个更好的解决方案,但深入研究roslyn文档以了解如何使用AST似乎有点复杂。你会碰巧知道如何使用它吗?这里还没有答案……取决于代码库的对立程度,你会发现ght可能需要也可能不需要担心
Namespace.Foo.myFunc(…)
(您要替换的)与
UnrelatedNamespace.Foo.myFunc(…)
(您不需要)。或者更糟糕的是,
使用UnrelatedNamespace;Foo.myFunc(…)
。或者
Foo
+newline+
/*现在调用myFunc*/.myFunc(…)
-跨多行拆分的方法调用。或别名:
使用Foo=UnrelatedNamespace.Bar;Foo.myFunc(…)
.Wow,这太令人印象深刻了。在走Roslyn之路之前,我只需要多次传递源代码和
RegexOptions.Singleline
标志。在95%的情况下应该可以。@oligofren你有没有不起作用的例子?我想可以添加新行。Regex更改为处理新行。Watch检查注释中是否存在误报。
Foo.myFunc(0/*”)*/
-在这种特定情况下,这可能不是问题。