商城首页欢迎来到中国正版软件门户

您的位置:首页 >如何使用正则表达式对输入数字进行匹配详解

如何使用正则表达式对输入数字进行匹配详解

  发布于2026-05-03 阅读(0)

扫一扫,手机访问

前言

最近在处理一个具体的需求:如何给输入框设置一个有符号整数的范围限制。像0到255这种小范围,网上资料一抓一大把。但一旦涉及到int16、int32甚至int64的完整数值区间,比如-32768到32767,现成的、清晰的解决方案就没那么好找了。网上的教程要么从最基础的正则语法讲起,篇幅很长;要么给出的模式过于笼统。其实我们想要的很简单:一个能精准校验数字是否落在特定范围内的正则表达式。

我花了一些时间琢磨,总结出了一套相对清晰的构建思路。接下来就分享一下我的理解,当然,**方法未必是最优的**,权当抛砖引玉,如果各位有更巧妙的方案,欢迎不吝指教。

正文

下面我们会一步步构建这个正则表达式,过程中会用到一些元字符,我们边做边解释。

我们就以匹配`int8`类型(范围-128 ~ 127)为例来说明。为了逻辑清晰,我们先搞定`0~127`这个非负区间。

从简单范围开始:0~15

首先,两个重要的定位符:`^`代表字符串开始,`$`代表字符串结束。用它们把模式包起来,可以确保匹配整个输入,而不是一部分。

匹配0到5很简单:`^[0-5]$`。中括号`[]`表示一个字符集,匹配其中的任意单个字符。

那0到15呢?数字15是两位的,这里就需要一点技巧了——从高位向低位拆解。

  • 当十位是1时,个位只能是0到5,模式是:`1[0-5]`。
  • 当十位是0时(即只显示个位数),个位可以是0到9,模式是:`[0-9]`。

现在,用一个圆括号`()`把这两个可能性组合起来,中间用竖线`|`(表示“或”)连接,就得到了:`^(1[0-5]|[0-9])$`。

在正则中,`\d`等价于`[0-9]`,所以上面可以简写为`^(1[0-5]|\d)$`。注意,在诸如Qt的C++环境中,`\`是转义字符,所以需要写成`\\d`,即:`"^(1[0-5]|\\d)$"`。

如何使用正则表达式对输入数字进行匹配详解

引入负数:-15 ~ 15

有了0~15的基础,扩展到包含负数就相对容易了。一个直观的想法是:匹配一个负号加0~15,或者直接匹配0~15。

初步尝试:`"^((-1[0-5]|\\d)|(1[0-5]|\\d))$"`。这个模式有个小问题:左边的`\d`匹配了0~9,这会导致它能匹配到“-0”这种情况,而通常我们不需要负零。

解决方法很简单,把左边负号后的`\d`范围从`[0-9]`改为`[1-9]`,只匹配1到9即可。于是,最终的-15~15匹配模式为:
`"^((-1[0-5]|[1-9])|(1[0-5]|\\d))$"`。

如何使用正则表达式对输入数字进行匹配详解

当然,这个模式在正负两部分有重复,看起来不够精简。不过对于理解原理来说,先保证正确性更重要。市面上肯定存在更优化的写法,这里我们先把握住核心思路。

挑战更大范围:int16 (-32768 ~ 32767)

现在,我们来啃一块硬骨头:`int16`的完整范围。方法论和之前一样:先解决非负部分(0~32767),然后处理负数部分(-32768 ~ -1),最后合并。

**第一步:构建0~32767的匹配模式**

关键在于“按位截断”。我们从最大值32767开始,逐位分析:

  1. 匹配32760~32767:当前三位是“327”时,个位只能是0~7。模式:`3276[0-7]`。
  2. 匹配32700~32759:当前两位是“327”时,后两位的范围是00~59。模式:`327[0-5]\d`。
  3. 匹配32000~32699:当数字以“32”开头时,后三位范围是000~699。模式:`32[0-6]\d{2}`。这里的`{2}`表示前面的`\d`重复恰好两次。
  4. 匹配30000~31999:当数字以“3”开头时,后四位范围是0000~1999。模式:`3[0-1]\d{3}`。
  5. 匹配10000~29999:对于所有五位数,且万位是1或2的,后面四位可以任意(因为肯定不会超过30000)。模式:`[1-2]\d{4}`。
  6. 匹配1000~9999:对于四位数,千位可以是1~9,后面三位任意。可以用一个简洁的模式覆盖100~9999:`[1-9]\d{1,3}`。`{1,3}`表示`\d`重复1到3次,这覆盖了100~999(三位)、1000~9999(四位)。
  7. 匹配0~9:最后,别忘了单个数字。模式:`\d`。

把这些所有情况用“或”运算符`|`连接起来,就得到了0~32767的完整匹配模式:

"^(3276[0-7]|327[0-5]\\d|32[0-6]\\d{2}|3[0-1]\\d{3}|[1-2]\\d{4}|[1-9]\\d{1,3}|\\d)$"

**第二步:构建-32768 ~ -1的匹配模式**

负数部分逻辑类似,但需要注意边界(最大值是-32768,最小值是-1)且排除“-0”。只需在正数部分模式上稍作调整:

  • 左边加上负号`-`。
  • 因为正数部分已经匹配了0,所以负数部分个位不应再出现0。我们可以通过调整最后那个覆盖范围较广的模式来实现:将正数模式中的`[1-9]\d{1,3}`在负数端改为`[1-9]\d{0,3}`,使其能匹配1到9999(因为负号已经在了)。同时,最大值的边界需要从32767调整为32768。

因此,-32768 ~ -1的模式为:

"^-(3276[0-8]|327[0-5]\\d|32[0-6]\\d{2}|3[0-1]\\d{3}|[1-2]\\d{4}|[1-9]\\d{0,3})$"

**第三步:合并为int16的最终模式**

最后,用“或”运算符将负数和正数(包含0)两部分组合:

"^(-(3276[0-8]|327[0-5]\\d|32[0-6]\\d{2}|3[0-1]\\d{3}|[1-2]\\d{4}|[1-9]\\d{0,3})|(3276[0-7]|327[0-5]\\d|32[0-6]\\d{2}|3[0-1]\\d{3}|[1-2]\\d{4}|[1-9]\\d{1,3}|\\d))$"

如何使用正则表达式对输入数字进行匹配详解

总结

通过上述从简到繁的拆解,我们可以清晰地看到,构建一个匹配特定整数范围的正则表达式,其核心思路是:从最大值开始,按位数逐级分类讨论,并用“或”逻辑覆盖所有合法情况。处理负数时,则在正数模式基础上加上负号并小心调整边界以避免负零。

虽然最终得到的正则表达式看起来很长,但结构是清晰的,每一步都有迹可循。按照这个方法论,`int32`(范围-2147483648 ~ 2147483647)或更大的`int64`范围,虽然模式字符串会非常长,但构建的原理是完全一样的。

当然了,必须承认,这种方法写出的正则并非最简洁或最高效的,它更侧重于可理解和可构建。在实际应用中,如果仅用于输入校验,或许有更巧妙的思路或现成的库可以借鉴。希望这篇分享能为你提供一个可靠的起点,也欢迎大家一起探讨更优的解决方案。

本文转载于:https://www.jb51.net/article/264541.htm 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注