正则表达式匹配非零前缀数字 *OR* 字母数字

Posted

技术标签:

【中文标题】正则表达式匹配非零前缀数字 *OR* 字母数字【英文标题】:Regular expression to match non-zero prefixed numeric *OR* alphanumeric 【发布时间】:2014-03-05 05:00:51 【问题描述】:

我编写了一个正则表达式,它与符合Semantic Versioning 2.0.0 规范的字符串匹配(见下文)。

表达式的中间部分处理预发布版本的解析。此部分以连字符 (-) 为前缀,并且可以有一个或多个用句点 (.) 分隔的标识符。每个标识符都是字母数字(0-9、A-Z、a-z 或连字符),但如果标识符是数字,则它必须以前导零开头

是否有更简洁的方式来表示我用来执行非零前缀规则的交替组?

此正则表达式适用于 .NET,使用“x”模式编写,以允许 cmets 并忽略空格。

^

# ====================================
# Main Major.Minor.Path version number
# ====================================
(?<version>
    (?<major>[1-9]\d*|0)
    \.
    (?<minor>[1-9]\d*|0)
    \.
    (?<patch>[1-9]\d*|0)
)

# ===========================
# Optional preprelease string
# ===========================
(?:
    -                                   # Hyphen indicates start of prerelease.
    (?<prerelease>
        #======================================================================
        # CONFUSION STARTS HERE
        (?:
            [1-9]\d*                    # Numeric identifier (no leading zero).
            |
            [A-Za-z-]+                  # Alpha identifier.
            |
            \d+[A-Za-z-]+[0-9A-Za-z-]*  # Alphanumeric starting w/ numeric.
            |
            [A-Za-z-]+\d+[0-9A-Za-z-]*  # Alphanumeric starting w/ alpha.
        )
        # CONFUSION ENDS HERE - ish
        #======================================================================
        (?:
            \.                          # start of another identifier.
            (
                [1-9]\d*
                |
                [A-Za-z-]+
                |
                \d+[A-Za-z-]+[0-9A-Za-z-]*
                |
                [A-Za-z-]+\d+[0-9A-Za-z-]*
            )
        )*
    )
)?

# =====================
# Optional build string
# =====================
(?:
    \+                                  # Plus sign indicates start of build string.
    (?<build>
        [0-9A-Za-z-]+
        (?:
            \.                          # start of another identifier.
            [0-9A-Za-z-]+
        )*
    )
)?

$

我认为该解决方案可能与环视运算符有关,但我不确定如何去做。

【问题讨论】:

看起来不错,有什么问题? 本身没问题,@sln。不过,这是一个相当长的正则表达式,我想知道是否有可能降低中间部分的复杂性并使其意图更加明显。我在想那些跟着我的人,真的。我不善良吗? ;) 【参考方案1】:

或许可以稍微缩短售前赛编辑 为可能受到回溯困扰的 [1-9] 添加了一个可能的修复方法。 使用前瞻。

 (?:
       -
       (?<prerelease>
            (?:
                 [1-9] \d* (?![\w-])
              |  \d+ [A-Za-z-]+ [0-9A-Za-z-]* 
              |  [A-Za-z-]+ (?: \d+ [0-9A-Za-z-]* )?
            )
            (?:
                 \.
                 (?:
                      [1-9] \d* (?![\w-]) 
                   |  \d+ [A-Za-z-]+ [0-9A-Za-z-]* 
                   |  [A-Za-z-]+ (?: \d+ [0-9A-Za-z-]* )?
                 )
            )*
       )
  )?

【讨论】:

啊哈,回溯问题的巧妙解决方案。

以上是关于正则表达式匹配非零前缀数字 *OR* 字母数字的主要内容,如果未能解决你的问题,请参考以下文章

常用数字与字母的正则表达式

正则表达式匹配指定数据和字母

常见的正则匹配

php正则匹配数字

求一个正则表达式 判断只能是数字、字母、下划线

常用的re模块的正则匹配的表达式