正则表达式匹配有效的命名空间名称

时间:2011-05-12 08:21:27

标签: c# regex

我以前曾问过这个问题,但是我尝试了谷歌,但没有找到答案。也许我使用了错误的关键字。

是否可以使用正则表达式来匹配有效的C#名称空间名称?


更新

感谢大家的答案和研究!这个问题比我预期的要复杂得多。正如Oscar MederosJoey指出的那样,有效的命名空间不能包含C#保留关键字,并且可以包含比拉丁字母多得多的Unicode字符。

但是我当前的项目只需要在语法上验证名称空间。所以我接受了primfaktor的答案,但我对所有答案都赞不绝口。

4 个答案:

答案 0 :(得分:4)

我知道问题是如何使用正则表达式验证命名空间,但另一种方法是让编译器完成工作。我不确定我在这里得到的100%的错误,它确实工作得很好。我为我目前正在工作的项目创建了这个ValidationRule:

using System.CodeDom.Compiler;
using System.Windows.Controls;
using Microsoft.CSharp;
using System.Text.RegularExpressions;

namespace Com.Gmail.Birklid.Ray.CodeGeneratorTemplateDialog
{
    public class NamespaceValidationRule : ValidationRule
    {
        public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
        {
            var input = value as string;
            if (string.IsNullOrWhiteSpace(value as string))
            {
                return new ValidationResult(false, "A namespace must be provided.");
            }
            else if (this.doubleDot.IsMatch(input))
            {
                return new ValidationResult(false, "'..' is not valid.");
            }
            var inputs = (value as string).Split('.');
            foreach (var item in inputs)
            {
                if (!this.compiler.IsValidIdentifier(item))
                {
                    return new ValidationResult(false, string.Format(cultureInfo, "'{0}' is invalid.", item));
                }
            }
            return ValidationResult.ValidResult;
        }

        private readonly CodeDomProvider compiler = CSharpCodeProvider.CreateProvider("CSharp");
        private readonly Regex doubleDot = new Regex("\\.\\.");
    }
}

答案 1 :(得分:3)

如果您想知道字符串是否可以用作命名空间,您应该参考The C# Language Specifications并查看验证命名空间的语法。

命名空间应该是由identifiers分隔的.序列。例如:

identifier
identifier.identifier
identifier.identifier.identifier
...

什么是identifier

available_identifier@any_identifier

available_identifierany_identifier但不能是语言保留的keyword

any_identifier如下:

(_|letter)(letter|number)*

修改
我必须说这个正则表达式真的很复杂。请记住有必要检查是否使用了保留关键字,以下是保留关键字列表:

  

抽象作为基本bool break byte的情况   catch char检查类const   继续十进制默认委托   double else枚举事件显式extern   为了foreach,最后修复了浮动   goto隐含在int接口中   内部是锁定长命名空间新   null对象操作符out覆盖   私人保护公众   readonly ref返回sbyte密封短   sizeof stackalloc静态字符串结构   切换这个抛出真的尝试typeof uint   ulong unchecked unsafe ushort using   

时虚拟空虚易变

你不能拆分验证,可能用C#或任何其他语言创建一个方法来验证它而不是只使用一个正则表达式吗?

说实话,我建议你做这两件事:

  1. 实现该语法的解析器(请参阅参考资料)。您可以手动或使用ANTLR
  2. 等工具来完成
  3. 实现一个方法,该方法接受您要验证的字符串(让我们称之为str)并编写如下文件:

    namespace str
    {
       class A {}
    }
    
  4. 并尝试使用msbuild或任何C#编译器编译它:)。如果它出错,那么您就知道该单词不正确:)

答案 2 :(得分:3)

对我来说,这很有效:

^using (@?[a-z_A-Z]\w+(?:\.@?[a-z_A-Z]\w+)*);$

它使用C#中的行进行匹配,并在第一个(也是唯一的)匹配组中返回完整的命名空间。您可能希望删除^$以允许缩进和尾随评论。

在RegExr上

Example

答案 3 :(得分:0)

这个怎么样......

(?:[A-Z][a-zA-Z0-9\._]+)+[a-z0-9_]