正则表达式

我不认为只用正则表达式就可以做到这一点,但我不是专家所以我认为值得一提。

我正在尝试使用.NET正则表达式进行大量搜索和替换C#代码。 我想要做的是找到一行代码,其中在DateTime类型的变量上调用特定函数。 例如:

axRecord.set_Field("CreatedDate", m_createdDate); 

我知道它是一个早期的日期时间变量b / c代码文件将是行:

 DateTime m_createdDate; 

但似乎我不能在负面的后视中使用命名组,如:

 (?<=DateTime \k.+?)axRecord.set_[^ ]+ (?[^ )]+) 

如果我尝试匹配变量声明和函数调用之间的所有文本,如下所示:

 DateTime (?[^;]+).+?axRecord.set.+?\k 

它将找到第一个匹配 – 首先基于声明的第一个变量 – 然后它找不到任何其他匹配,因为代码的布局如下:

 DateTime m_First; DateTime m_Second; ... axRecord.set_Field("something", m_First); axRecord.set_Field("somethingElse", m_Second); 

第一个匹配包含第二个变量声明。

有没有一种很好的方法可以用正则表达式来做到这一点,或者我是否必须在我的逻辑中使用脚本?

试试这个:

 @"(?s)set_Field\(""[^""]*"",\s*(?\w+)(?<=\bDateTime\s+\k\b.+)" 

通过首先执行lookbehind,您将强制正则表达式以特定顺序搜索方法调用:声明变量的顺序。 你想要做的是首先匹配一个可能看起来的方法调用,然后使用lookbehind来validation变量的类型。

我只是粗略猜测了与方法调用匹配的部分。 就像其他人所说的那样,无论你使用哪种正则表达式都必须根据你的代码量身定制; 没有一般解决方案。

看看我对这个问题的回答从C#文件中获取方法内容

它提供了指向页面的链接,这些页面显示了如何使用内置的.net语言解析器来简单可靠地执行此操作(即不是通过询问“我正在搜索的用法”,而是通过使用VS代码正确解析代码)解析工具)。

我知道这不是RegEx的答案,但我认为RegEx不是答案。

使用单个正则表达式很难做到这一点。 但是,如果您考虑使用一些状态处理行,则可以执行此操作。

注意:我无法确切地告诉你在axRecord线上想要匹配的内容,因此您可能需要适当地调整该正则表达式。

 void Process(List lines) { var comp = StringComparer.Ordinal; var map = new Hashsetcomp); var declRegex = new Regex("^\s(?\w+)\s*(?m_\w+)\s*";); var toReplaceRegex = new Regex("^\s*axRecord.set_(?.*(?m_\w+).*)"); for( var i = 0; i < lines.Length; i++) { var line = lines[i]; var match = declRegex.Match(line); if ( match.Success ) { if ( comp.Equals(match.Groups["type"], "DateTime") ) { map.Add(comp.Groups["name"]); } else { map.Remove(comp.Groups["name"]); } continue; } match = toReplaceRegex.Match(line); if ( match.Success && map.Contains(match.Groups["name"]) ) { // Add your replace logic here } } 

使用正则表达式无法完成此操作。 首先,C#的语法不规则; 但更重要的是,你在谈论分析词汇无关的表达。 对于这类事情,您将需要完整的语义分析。 这意味着词法分析器,解析器,名称绑定和最终类型检查器。 获得带注释的AST后,您可以查找所需的字段,然后阅读该类型。

我猜这比你想做的工作要多得多,因为它只是一个完整的C#编译器的一半。

这很奇怪。 我设法建立一个确实找到它的正则表达式,但它只匹配第一个。

 (?<=private datetime (?<1>\b\w+\b).+?)set_field[^;]+?\k<1> 

所以看起来如果我不能在lookbehind中使用命名组,我至少可以在lookbehind中建立一个命名组,并在匹配中使用它。 但是看起来当它只匹配函数调用(这就是我想要的)时,插入位置被移动到那一行,因此它找不到任何新的匹配,因为它传递了它们的声明。 或者我可能不明白引擎是如何工作的。

我想我正在寻找的是一个正则表达式选项,告诉它查看匹配内部以获得更多匹配。 考虑到它,似乎也需要基本的html正则表达式解析。 你找到一个标签,然后它是结束标签,整个页面都包含在那个匹配中,所以除非你递归地将模式应用于每个匹配,否则你将找不到任何其他标签。

任何人都知道这件事,还是我说疯了?