2010-08-13 67 views
6

我想验证脚本引擎的一些C#源代码。我想确保只有System.Math类成员可能被引用。我正在尝试创建一个正则表达式,该正则表达式将匹配一个点,后跟一个大写字母,后跟任意数量的单词字符,以不以System.Math开头的单词边界结束。正则表达式头痛

我开始用这样的:

(?<!Math)\.[A-Z]+[\w]* 

工作正常进行:

return Math.Max(466.89/83.449 * 5.5); // won’t flag this 
return Xath.Max(466.89/83.449 * 5.5); // will flag this 

它正确地匹配。最大时,它不是由数学之前。但是,现在我试图扩展正则表达式来包含System,我无法使其正常工作。

我已经试过正则表达式的这些排列多:

((?<!System\.Math)\.[A-Z]+[\w]*) 
((?<!(?<!System)\.Math)\.[A-Z]+[\w]*) 
((?<!System)\.(?<!Math)\.[A-Z]+[\w]*) 
((?<!System)|(?<!Math)\.[A-Z]+[\w]*) 
((?<!System\.Math)|(?<!Math)\.[A-Z]+[\w]*) 

使用这些语句:

return System.Math.Max(466.89/83.449 * 5.5); 
return System.Xath.Max(466.89/83.449 * 5.5); 
return Xystem.Math.Max(466.89/83.449 * 5.5); 

我已经试过了我能想到的一切,但它要么始终匹配第二个元素(上面的.Math或.Xath)或它不匹配任何。

如果有人会怜悯我,并指出我做错了什么,我会大大appit它。

由于提前, 韦尔顿

+0

我以为肯定我有一个解决方案,但现在我重新发现了所有列出的表达式,并破坏了我的大脑。确实非常棘手! – 2010-08-13 00:35:53

+0

'Math.'会独自出现,还是总是以'System.'开头? – 2010-08-13 00:36:17

+4

您是否考虑过使用编译器(CSharpCodeProvider),然后使用CodeDom对象图来扫描除System.Math之外的其他引用?这将是防弹,更可读,更灵活。 – 2010-08-13 00:39:10

回答

2

诀窍是确保你永远不会在开始时在任何地方开始匹配成员名称。然后,使用lookahead来简单的问题来确定您正在查看的内容是否以System.Math.开头。试试这个正则表达式:

(?<![\w.])(?!(?:System\.)?Math\.)(?:[A-Z]\w*\.)+[A-Z]\w*\b 

的回顾后保证比赛不以字(\w)或合格的成员名称(.)的中间位置的中间开始。现在,如果前瞻失败,它不能跳到下一个组件的开头(例如System.Math.中的Math.),然后重试。这是全部或没有。

但是,如果此前没有System.,则此将与匹配Math.Max。你真的需要这个,还是仅仅是为全名开发一个正则表达式的中间步骤?

编辑:我继续前进,并使System.部分可选。

+0

这也行! – dawg 2010-08-13 01:28:08

2

如果你只是在寻找你的例子说明,此正则表达式将做到这一点。

^[\w\s]*?[A-Z]\w+\.[A-Z]\w+\.(?<!System\.Math\.)

它只要比System.Math.XXX这是其他所有呼叫匹配为:a)有在呼叫的两个.,b)该呼叫是在一行上。

return System.Math.Max(466.89/83.449 * 5.5); // no match 
return System.Xath.Max(466.89/83.449 * 5.5); // match 
return Xystem.Math.Max(466.89/83.449 * 5.5); // match 
System.Math.Max(466.89/83.449 * 5.5); // no match 
System.Xath.Max(466.89/83.449 * 5.5); // match 
Xystem.Math.Max(466.89/83.449 * 5.5); // match 
return System.Math.Max(466.89/83.449 * 5.5); // no match 
return System.Xath.Max(466.89/83.449 * 5.5); // match 
return Xystem.Math.Max(466.89/83.449 * 5.5); // match 
Math.Max(466.89/83.449 * 5.5);    // no match - only one '.' 
System.Max.Math(466.89/83.449 * 5.5);  // match 

虽然我同意评论意见,任何正则表达式都非常脆弱,只应该被认为是一种文本编辑器类型的帮助。如果你希望它是防弹的,你需要一个解析器。

+0

返回时不起作用Xath.Max(466.89/83.449 * 5.5); – 2010-08-13 01:42:59

+0

@Richard:OP状态他想最终匹配吗?我的理解是,'Math.Max(466.89/83.449 * 5.5);''和'Xath.Max(466.89/83.449 * 5.5);'其中正则表达式的中间发展... – dawg 2010-08-13 01:48:51

+0

不确定...如果他说没关系,那你就明白了。 – 2010-08-13 02:07:04