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

本文关键字:正则表达式 命名空间 有效 用于 | 更新日期: 2023-09-27 17:56:06

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

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


更新:

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

但是我当前的项目只需要在语法上验证命名空间。所以我接受了primfaktor的回答,但我对所有的答案都投了赞成票。

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

对我来说

,这有效:

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

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

关于正则表达式的示例。

我知道

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

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("''.''.");
    }
}

如果想知道字符串是否可以用作命名空间,则应参阅 C# 语言规范并查看验证命名空间的语法。

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


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

什么是identifier

available_identifier@any_identifier

available_identifierany_identifier,但不能是语言保留的keyword

any_identifier如下:

(_|letter)(letter|number)*

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

抽象为基本布尔断字节大小写 捕获字符检查类常量 继续十进制默认委托执行 双倍其他枚举事件显式外部 假 最终固定浮点数 如果隐含在 int 接口中,则转到 内部是锁定长命名空间新 空对象运算符输出覆盖 参数 私人 受保护 公共 只读引用返回字节密封短 大小的堆栈分配 静态字符串结构 切换此抛出真尝试类型UINT 乌龙 未经检查 不安全 使用 虚拟空隙易失性,而

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

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

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

    namespace str
    {
       class A {}
    }
    

并尝试使用 MSBbuild 或任何 C# 编译器:)编译它。如果它给出错误,那么您就知道该单词不正确:)

这个怎么样...

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