如何用正则表达式提取C#文件中的字段、属性及其引用位置?
从C#文件中提取字段与属性名的正则优化方案
需求与问题背景
需要从C#文件中匹配并提取类的字段名、属性名,示例代码如下:
using System; ... // usings using Grpc.Net.Client; using UI = Gtk.Builder.ObjectAttribute; namespace DummyProject; public class MainWindow : Window { [UI] private readonly MenuItem _aboutMenuItem; [UI] private readonly MenuItem _openFolderItem; [UI] private readonly MenuItem _openFileItem; [UI] private readonly Viewport _fileViewport; [UI] private readonly Notebook _codeNotebook; private readonly SourceView _codeSourceView; private readonly FileViewer _fileViewer; private readonly Files.FilesClient _filesClient; public FileSystemViewer FileSystemViewer { get; } public MainWindow() { _fileViewer = new FileViewer(); // some code } // methods }
期望提取结果:_aboutMenuItem, _openFolderItem, _openFileItem, _fileViewport, _codeNotebook, _codeSourceView, _fileViewer, _filesClient, FileSystemViewer
此前尝试的正则表达式匹配结果不符合预期:
^(?:(?=[^()]*$))?(?:(?!.*\b(namespace|return|using|class)\b))[\t \b]*(?:[\[\]a-zA-Z0-9_.]+\s+)?(?:(?:private|public|protected|internal)\s+)?(?:(?:static readonly|static|const|readonly|volatile|virtual|override)\s+)?(?:(?:[a-zA-Z0-9\.]+)\s+)?(\w+)\s*
正则优化方案
核心调整思路
- 聚焦类内部的字段与属性定义,排除方法内部的变量引用
- 完善特性标签(如
[UI])的匹配逻辑 - 简化冗余断言,避免不必要的范围限制
优化后的正则表达式
^\s*(?:\[.*?\]\s*)?(?:private|public|protected|internal)\s+(?:static\s+)?(?:readonly\s+)?[\w\.]+\s+([\w_]+)\s*(?:;|{.*?})
正则各部分说明
^\s*:匹配行首的空白缩进,适配代码格式(?:\[.*?\]\s*)?:可选匹配特性注解(如[UI])及其后的空白,支持带特性的字段定义(?:private|public|protected|internal)\s+:匹配访问修饰符,确保是类成员定义(?:static\s+)?:可选匹配static关键字,支持静态成员(?:readonly\s+)?:可选匹配readonly关键字,支持只读成员[\w\.]+\s+:匹配成员类型名,支持带命名空间的类型(如Files.FilesClient)([\w_]+):捕获目标字段/属性名,兼容下划线开头的命名风格\s*(?:;|{.*?}):匹配行尾的分号(字段)或属性的访问器块(如{ get; }),确保是成员定义而非方法内的变量
扩展说明
- 若需支持更多修饰符(如
virtual、override),可在访问修饰符后添加(?:virtual\s+|override\s+)? - 处理多行定义的属性时,需开启正则的
DOTALL模式(让.匹配换行符)
内容的提问来源于stack exchange,提问作者Moonderland
相关产品推荐
相关产品推荐

