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

C# 正则表达式以匹配有效的命名空间名称,c#,regex,C#,Regex,我以为以前有人问过这个问题,但我试过谷歌,但没有找到答案。也许我用错关键词了 是否可以使用正则表达式匹配有效的C#命名空间名称 更新: 谢谢大家的回答和研究!这个问题比我想象的要复杂得多。正如和指出的,有效的命名空间不能包含C#保留关键字,并且可以包含比拉丁字母多得多的Unicode字符 但我当前的项目只需要对名称空间进行语法验证。所以我接受了的答案,但我对所有答案都投了赞成票。如果您想知道字符串是否可以用作名称空间,您应该参考并查看验证名称空间的语法 名称空间应该是一系列标识符,由分隔。例如

我以为以前有人问过这个问题,但我试过谷歌,但没有找到答案。也许我用错关键词了

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


更新:

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


但我当前的项目只需要对名称空间进行语法验证。所以我接受了的答案,但我对所有答案都投了赞成票。

如果您想知道字符串是否可以用作名称空间,您应该参考并查看验证名称空间的语法

名称空间应该是一系列
标识符
,由
分隔。例如:

标识符

标识符。标识符

identifier.identifier.identifier

什么是
标识符

可用的\u标识符
@任何\u标识符

可用的\u标识符
任何\u标识符
,但不能是该语言保留的
关键字

任何_标识符
如下所示:

(|字母)(字母编号)*

编辑:
我必须说这个正则表达式非常复杂。考虑到有必要检查是否未使用保留关键字,以下是保留关键字的列表:

抽象为基布尔中断字节大小写 catch char checked类常量 继续十进制默认委托do 双else枚举事件显式外部 foreach的false最终固定浮点 如果在int接口中隐式,则转到 内部锁长命名空间是新的 空对象运算符输出覆盖 params私有保护公共 只读参考返回sbyte密封短路 stackalloc静态字符串结构的大小 切换此抛出的真尝试类型uint ulong unchecked不安全的ushort使用 虚虚空易失性

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

老实说,我建议你做以下两件事中的任何一件:

  • 实现该语法的解析器(参见参考资料)。您可以手动或使用ANTLR之类的工具来完成
  • 实现一个方法,该方法获取要验证的字符串(我们称之为
    str
    ),并编写如下文件:

    namespace str
    {
       class A {}
    }
    
  • 并尝试使用msbuild或任何C#编译器编译它。如果它给出了一个错误,那么您就知道这个单词是不正确的。
    :)

    这个怎么样

    (?:[A-Z][a-zA-Z0-9\._]+)+[a-z0-9_]
    
    对我来说,这很有效:

    ^using (@?[a-z_A-Z]\w+(?:\.@?[a-z_A-Z]\w+)*);$
    
    它使用C#中的行进行匹配,并在第一个(也是唯一一个)匹配组中返回完整的命名空间。您可能需要删除
    ^
    $
    以允许缩进和尾随注释


    关于RegExr。

    我知道问题是如何使用regex验证名称空间,但另一种方法是让编译器完成这项工作。我不确定我这里的内容是否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("\\.\\.");
        }
    }
    

    现在还不清楚你想要实现什么。请提供一个示例。您想匹配命名空间的每个部分还是验证它?@Daniel Hilgarth,@Dve:我想知道字符串是否可以用作C#命名空间名称。例如:MySolution1.Projects2_uu.Name_uspace此匹配无效的命名空间,不能包含-或以数字开头。也应该真正从资本开始letters@Dve看看我写的。我正在查找命名空间可以包含的有效字符。顺便问一下,你确定它不能包含数字吗?
    Namespace1
    是否无效?我不这么认为。抱歉打字错误。。。它不能以数字开头。还要注意的是,字母不需要是ASCII码,而是几个Unicode类的onf码,这使得这个问题相当复杂。@Joey。不仅如此,您还将看到
    连接字符
    组合字符
    格式化字符
    (Cf、Mn、Mc或Pc类的unicode字符)。天哪:)事实上,它比这更复杂。请看我的答案。C#支持Unicode。标识符中的有效字母比拉丁字母多得多…这将失败
    不是有效的命名空间,但不仅仅是该命名空间,
    摘要
    作为
    。。两者都不是。您的正则表达式与有效的名称空间不匹配,比如
    @a
    ,只是给您举个例子。好的,我只考虑语法正确的名称空间,而不是语义正确的名称空间。对于这些,您可能无法构造正则表达式。但是
    @
    怎么办?
    @
    怎么办?它用于字符串的开头。它通常用于给系统保留的名称,比如
    @string
    谢谢奥斯卡,我不知道这个。我使用了^using(@?[a-z_a-z]\w*(?:\.@[a-z_a-z]\w*);$允许点分隔部分仅为一个字符长