首页 > 解决方案 > 正则表达式在第一个零之后只匹配零

问题描述

使用正则表达式,我如何确保在第一个零之后只有零?

ABC1000000 - valid
3212130000 - valid
0000000000 - valid
ABC1000100 - invalid
0001000000 - invalid

没有验证的正则表达式会是这样的 - [A-Z0-9]{10},确保它是 10 个字符。

标签: regex

解决方案


您可以将模式更新为:

^(?=[A-Z0-9]{10}$)[A-Z1-9]*0+$

模式匹配:

  • ^字符串的开始
  • (?=[A-Z0-9]{10}$)正向头,断言 10 个允许的字符
  • [A-Z1-9]*可选匹配任何字符[A-Z1-9]
  • 0+匹配 1+ 个零
  • $字符串结束

正则表达式演示

如果还允许不带零的值,则最后一个量词可以*匹配 0 次或更多次(@Deduplicator 的注释使用否定字符类的更短版本):

^(?=[A-Z0-9]{10}$)[^0]*0*$

使用 JavaScript 的示例:

const regex = /^(?=[A-Z0-9]{10}$)[^0]*0*$/;
["ABC1000000", "3212130000", "0000000000", "ABC1000100", "0001000000"]
.forEach(s =>
  console.log(`${s} --> ${regex.test(s)}`)
);


作为没有环视的替代方案,您还可以匹配您不想要的内容,并在第 1 组中捕获您想要保留的内容。

为确保在第一个零之后只有零,您可以在匹配 0 后立即停止匹配,然后匹配相同范围的 1 个字符而没有 0。

在交替中,第二部分可以捕获范围为 A-Z0-9 的 10 个字符。

^(?:[A-Z1-9]*0+[A-Z1-9]|([A-Z0-9]{10})$)

模式匹配:

  • ^字符串的开始
  • (?:轮换的非捕获组|
    • [A-Z1-9]*0+[A-Z1-9]匹配不应该出现的内容,在这种情况下,一个零后跟一个不带零的范围中的字符
    • |或者
    • ([A-Z0-9]{10})捕获组 1,匹配范围内的 10 个字符[A-Z0-9]
  • $字符串结束
  • )关闭非捕获组

正则表达式演示


推荐阅读