原文: https://geek-docs.com/regexp/regexp-tutorials/regular-expressions-match-numeric-ranges.html

正则表达式匹配数字范围,匹配单个数字的方式很简单,[0-9][0123456789]的简写形式,可以用来匹配任何一个数字。如果要匹配 0 到 255 中的所有数字,该怎么办呢?表达式[0-255]并不能达到目的。

下表所示为数字元字符

元字符 说明
\d 任何一个数字字符(等价于[0-9]
\D 任何一个非数字字符(等价于[^0-9]

正则表达式是为了匹配字符而设计的,而并不是为了匹配数字,所以当你使用正则匹配指定范围内的数字的时候你需要额外小心。表达式[0-255]并不能匹配 0 至 255 之间的数字。表达式[0-255]是一个字符集,它的含义是匹配 0,1,2,5 中任意一个字符,这个表达式等同于[0125]

正则引擎真正处理的是字符,所以数字 0 对于引擎来说是一个字符,而 255 对于引擎来说是长度为 3 的字符。所以如何要匹配 0 至 255 中的所有数字,我们需要让引擎匹配长度为一到三之间的字符。

  • [0-9] 可以匹配 0~9 之间的数字。
  • [1-9][0-9] 可以匹配 10~99 之间的数字。
  • [1-9][0-9][0-9] 可以匹配 100~999 之间的数字

但是匹配 0~255 略微复杂一点,因为我们要排除256至999之间的整数。

  • 1[0-9][0-9]可以匹配 100 至 199 。
  • 2[0-4][0-9]可以匹配 200 至 249 。
  • 25[0-5]可以匹配 250 至 255 。

你可以发现当我们匹配 0 到 255 之间的整数时,我们需要按照字符的长度来分割这个范围。在匹配三位整数的时候,如果百位是 1 ,那么十位和个位允许出现 0 至 9 之间的 10 个字符,如果百位是 2 ,那么十位和个位的字符将进一步做限制。

把前面三个部分用选择符连接起来,我们就得到了 0 至 255 之间所有的整数:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]

但是这个方法还存在一个缺陷:正则表达式通常允许部分匹配,所以这个表达式可以匹配到 12345 中的 123。

如下两种方法可以解决问题:

(1)词语边界 如果你在一个文档中所搜数字,你可以使用词语边界锁定数字的范围:\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b。因为选择符的优先级是最低的,所以我们要在选择外加上括号。这样引擎会先匹配第一个边界符\b,然后匹配整个选择符,最后匹配最后一个\b

(2)位置字符 如果你想验证用户输入内容,那么或许你想验证的是用户输入的完整内容,而不是其中的部分。你可以使用位置字符:^([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$。

以下一些常用的数字匹配:

  • 000..255: ^([01][0-9][0-9]|2[0-4][0-9]|25[0-5])$
  • 0 or 000..255: ^([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$
  • 0 or 000..127: ^(0?[0-9]?[0-9]|1[01][0-9]|12[0-7])$
  • 0..999: ^([0-9]|[1-9][0-9]|[1-9][0-9][0-9])$
  • 000..999: ^[0-9]{3}$
  • 0 or 000..999: ^[0-9]{1,3}$
  • 1..999: ^([1-9]|[1-9][0-9]|[1-9][0-9][0-9])$
  • 001..999: ^(00[1-9]|0[1-9][0-9]|[1-9][0-9][0-9])$
  • 1 or 001..999: ^(0{0,2}[1-9]|0?[1-9][0-9]|[1-9][0-9][0-9])$
  • 0 or 00..59: ^[0-5]?[0-9]$
  • 0 or 000..366: ^(0?[0-9]?[0-9]|[1-2][0-9][0-9]|3[0-5][0-9]|36[0-6])$
  • 正整数: ^[0-9]*[1-9][0-9]*$
  • 负整数: ^-[0-9]*[1-9][0-9]*$
  • 整数: ^-?d $
  • 浮点数: ^(-?d )(.d )?$
  • 正浮点数: ^(([0-9] .[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*.[0-9] )|([0-9]*[1-9][0-9]*))$
  • 复浮点数: ^(-(([0-9] .[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*.[0-9] )|([0-9]*[1-9][0-9]*)))$

Like this post? Share on:


doobom Avatar doobom is write a bug.
Comments

So what do you think? Did I miss something? Is any part unclear? Leave your comments below.

comments powered by Disqus

Keep Reading


Published

Category

RegEx

Tags

Stay in Touch

Get New Release Alert