C# 编写正则表达式模式以查找不带Select方法的IQueryable链接方法
在web应用程序中,我是开发团队的一员,我们使用实体框架作为ORM。当我们执行SQL查询时,通常会链接IQueryable methods实体框架提供的方法,从方法C# 编写正则表达式模式以查找不带Select方法的IQueryable链接方法,c#,regex,entity-framework,C#,Regex,Entity Framework,在web应用程序中,我是开发团队的一员,我们使用实体框架作为ORM。当我们执行SQL查询时,通常会链接IQueryable methods实体框架提供的方法,从方法Items()开始,这是我们特定于项目的数据库集模型投影。我一直在尝试编写一个正则表达式模式,该模式将查找不使用Select方法的查询 这就是我们的代码通常的样子 Cars.Items() .Where(x => x.Year == "1988") .Select(x => new { x.Registration
Items()
开始,这是我们特定于项目的数据库集模型投影。我一直在尝试编写一个正则表达式模式,该模式将查找不使用Select
方法的查询
这就是我们的代码通常的样子
Cars.Items()
.Where(x => x.Year == "1988")
.Select(x => new { x.Registration })
.ToList();
Cars.Items()
.Where(x => x.Id == 1923984)
.Select(x => new { x.Registration })
.FirstOrDefault;
这就是我想找到的问题
Cars.Items()
.Where(x => x.Id == 1923984)
.FirstOrDefault;
我曾尝试使用负前瞻排除具有Select()
方法的查询,但它们被包括在内,我正在努力寻找替代方法
\.Items\(.*\)(\s*\..*\(.*\))*(?!\.Select\(.+\))(\s*\..*\(.*\))\;
我要打破我的逻辑
所有查询都以此方法开始\.Items\(.*)
任意数量的链链接IQueryable方法(\s*\..*\(.*)*
应排除(?!\.Select\(.+\)
方法Select()
这可以是(\s*\..*\(.*\)\
、First()
、FirstOrDefault()
或类似的Single()
代码>结束查询
- 负面展望不起作用的原因是,您已经用此部件捕获了所有内容:
\.Items\(.*\)(\s*\..*\(.*\)*
你需要先展望负面,然后包括一切。试试这个正则表达式:
\.Items\(.*?\)(\W.*(!\)选择\(.+\))(\W.*)\代码>
在这里尝试一下:我也尝试过为此创建正则表达式。您可以在此处进行测试:
正则表达式:Cars(?>\(?!select)\w+(?:\([^)]*\)?\s*)+\代码>
与vendettamit给出的答案略有不同的是,这一答案抓住了整个陈述
编辑:那么它是如何工作的呢?
我尝试捕获重复的部分(.Items()
或.Select()
),以便模式更易于维护/遵循
汽车
我把Cars
放在开头,因为这样regex引擎就可以尽快知道下一组字符是否有趣。这减少了所需步骤的数量。也可以替换为\w+
,但由于整个文本中有更多字符与之匹配,因此需要执行更多步骤
(?>
我在这里启动一个原子组。这意味着正则表达式引擎在遵循正则表达式模式时不会回溯。这将大大提高性能,因为如果模式的一部分失败,它将不会尝试其他可能性
\.
逐字匹配
字符
(?!选择)
负向前看-仅在不选择时匹配。我在regex101.com上使用了不区分大小写的修饰符,但C#也支持此功能。否则只需将其更改为[Ss]elect
\w+
至少匹配一次任何单词字符a-zA-Z0-9
。这与where
或选择文本的一部分相匹配
(?:
我在这里启动了一个新的非捕获组。之所以这样做,是因为模式的下一部分是可选的(methods/lambda的()
部分)
\(
这只与(
字符字面上匹配
[^)]*
这将匹配所有内容(不包括任何内容。请参阅*
),直到遇到)
字符
\)
字面上匹配)
字符
)?
我关闭可选(请参见?
)组。请记住,这是每个方法/lambda的()
部分,但也可能是一个属性,因此()
部分必须是可选的
\s*
尽可能多次匹配任何空白字符(如空格、制表符和新行)
)+
在这里,我们结束与。其中(x=>x)
文本部分匹配的组(至少一次。请参见+
)
\代码>
匹配代码>字符
就这样!因此,在性能上最大的欺骗是汽车
部分和(?>
原子组。这对于正则表达式来说太难了。见鬼,即使有一个完全工作的C#解析器,这也不是一件小事!既然@dasblinkenlight提到了它。也许值得研究一下Roslyn编译器API来解析C#,并自动(在Visual Studio中)查找此类代码结构。您认为我尝试的负前瞻性是可能的吗?我正在寻找的模式不必复杂。请尝试此\.Items\(.*)(\W.*?)(\W.*。选择\(.+\)(\W.*))\
…而且只需要一半的步骤就可以匹配。+1!它们都很好。我还没有弄清楚它们是如何工作的,但根据vendettamit的评论,我将您的答案切换为可接受的答案。@exportr如果您仍然感兴趣,我已经解释了正则表达式的部分。:)@测量这很好,里面肯定有我不知道的部分。