【问题标题】:Match C# Unicode Identifier using Regex使用正则表达式匹配 C# Unicode 标识符
【发布时间】:2010-12-09 16:08:06
【问题描述】:

使用 .Net Regex 模式匹配 C# 标识符(特别是属性或字段名称)的正确方法是什么?

背景。我曾经使用以 ASCII 为中心的 @"[_a-zA-Z][_a-zA-Z0-9]*" 但现在 unicode 大写和小写字符是合法的,例如“AboöДЖem”。我应该如何将这些包含在模式中?

谢谢, 最大

【问题讨论】:

    标签: c# regex unicode character-properties


    【解决方案1】:

    根据http://msdn.microsoft.com/en-us/library/aa664670.aspx,忽略keywordunicode-escape-sequence的东西,

    @?[_\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}\p{Nl}][\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}\p{Nl}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\p{Cf}]*
    

    【讨论】:

    • 我认为您可以将\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo} 简化为\p{L}。此处使用的其他一些 char 类也是如此。我想如果这就是微软在他们的标准中加入的内容,那么做同样的事情可能是最简单的。
    • 这是编译器从源头确定它的方式,以防万一有人感兴趣:github.com/dotnet/roslyn/blob/…
    【解决方案2】:

    这是一个考虑到不允许的前导数字的版本:

    ^(?:((?!\d)\w+(?:\.(?!\d)\w+)*)\.)?((?!\d)\w+)$
    

    以下是 PowerShell 中的一些测试:

    [regex]$regex = '(?x:
        ^                        # Start of string
        (?:
            (                    # Namespace
                (?!\d)\w+        #   Top-level namespace
                (?:\.(?!\d)\w+)* #   Subsequent namespaces
            )
            \.                   # End of namespaces period
        )?                       # Namespace is optional
        ((?!\d)\w+)              # Class name
        $                        # End of string
    )'
    @(
        'System.Data.Doohickey'
        '_1System.Data.Doohickey'
        'System.String'
        'System.Data.SqlClient.SqlConnection'
        'DoohickeyClass'
        'Stackoverflow.Q4400348.AboöДЖem'
        '1System.Data.Doohickey' # numbers not allowed at start of namespace
        'System.Data.1Doohickey' # numbers not allowed at start of class
        'global::DoohickeyClass' # "global::" not part of actual namespace
    ) | %{
        ($isMatch, $namespace, $class) = ($false, $null, $null)
        if ($_ -match $regex) {
            ($isMatch, $namespace, $class) = ($true, $Matches[1], $Matches[2])
        }
        new-object PSObject -prop @{
            'IsMatch'   = $isMatch
            'Name'      = $_
            'Namespace' = $namespace
            'Class'     = $class
        }
    } | ft IsMatch, Name, Namespace, Class -auto
    

    【讨论】:

    • 这是否允许前导下划线?
    • @rory.ap 确实如此。 (允许前导下划线)
    • 不幸的是,此代码与 C# 的 @ 前缀不匹配,该前缀允许将 C# 关键字用作标识符。
    【解决方案3】:

    正则表达式中的预定义类是否解决了这个问题 \w 将匹配 öД。

    【讨论】:

    • 谢谢。现在我可以在 Glagolitic 和 Hieroglypics 中进行混合编程。 ;)
    • 您不能只使用 @"\w+" 来匹配标识符 - 它会包括以数字开头的单词 - 例如它将匹配“12abc”,这是一个无效的标识符。我建议 @"[\w-[0-9]]\w*" 作为解决方案。
    猜你喜欢
    • 2015-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-16
    • 1970-01-01
    • 2015-12-13
    • 2013-12-18
    • 1970-01-01
    相关资源
    最近更新 更多