醒者 發表於 2022-10-9 10:50:33

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

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">前言:</a></li><li><a href="#_label1">正文:</a></li><li><a href="#_label2">总结</a></li></ul></div><p class="maodian"><a name="_label0"></a></p><h2>前言:</h2>
<p>最近有一个区间范围限制,一般255数字以下的都能在网上薅到,但是需要弄一个int16、int32、int64范围的输入限制......在网上逛了很久都没找到,基本都是从0开始教学那种,我又不想看,觉得写的范围太大了,我就单纯的对数字进行校验,最终还是研究了一点点,先说说自己的理解,0如有觉得不对的地方或者还有更简单的方法,请大佬踢我一jio</p>
<p class="maodian"><a name="_label1"></a></p><h2>正文:</h2>
<p>下面会使用到一些元字符,边做边解释。</p>
<p>举例:做一个int8的输入限制,也是就是需要将输入框的限制设置在(-128 ~ 127)</p>
<p>先说0~127的限制范围:</p>
<p>首先需要先写 ^ $ 两个元字符,这两个的意思就是开始与结束的字符串搭配。如匹配 0~5的整数字符串,则就是&nbsp;^ $ (中括号为字符范围,匹配指定范围内的任意字符。例如,&#39;&#39; 可以匹配 &#39;a&#39; 到 &#39;z&#39; 范围内的任意小写字母字符)。</p>
<p>那如果是 0~15呢,15就是两个字符,需要从右边往左拆分,当第一位数字为1时,第二位数值的取值范围就只能是0~5,所以出现了第一种组合方式 1,当第一位为0时,也就是不显示十位,只存在个位数,那么第二种组合方式就是,结合第一种和第二种的组合方式,^(1|)$ 中间的|符号可以理解为或运输,就是既可以匹配1的数字,也可以匹配的数字,圆括号可以理解为一个组合。此处使用Qt测试代码为:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202210/2022100910465110.png" /></p>
<p>因为元字符中:</p>
<table><tbody><tr><td>\d</td><td><p>匹配一个数字字符。等价于 。</p></td></tr></tbody></table>
<p>所以此处的 &quot;^(1|)$&quot; 组合方式可以缩写成&nbsp;&quot;^(1|\d)$&quot;,因为在Qt中使用\d好像被识别成转义字符了,提示如下面一样:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202210/2022100910465111.png" /></p>
<p>所以需要将 \d 写成 \\d ,即为&nbsp; &quot;^(1|\\d)$&quot;</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202210/2022100910465112.png" /></p>
<p>&nbsp;那么,至此 0~15 整数的正则表达式就写完了,如果我们这里需要写&nbsp; -15~15 的取值范围又该怎么弄呢? 一样的只需要将 0~15照着抄过来就行。先写成&quot;^((-1|\\d)|(1|\\d))$&quot;,大家会发现我写了两次0~15的取值范围,中间用到了&ldquo;|&rdquo;或运算符,在最左侧加了一个&ldquo;-&rdquo;负号,给人的感觉好像是-15~15,但是这里左侧的取值范围存在0的情况,也就是左边的会出现 -0 的匹配,是因为左边的 \\d包含了 0~9的数字,这里面包含了0,所以我们不想要这种情况的出现,只需要将左边的 \\d改为 就可以啦,所以-15~15 的匹配方式为&nbsp;&quot;^((-1|)|(1|\\d))$&quot;</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202210/2022100910465113.png" /></p>
<p>当然这只是我的简单理解,可能会存在更好的方式,避免左右两侧重复的匹配字符串太多,而又做不到复用的情况,也请大佬指出。</p>
<p>最后我们要来匹配一个&nbsp;int16的取值范围,因为int16的范围为整数 -32768 ~ 32767,所以我们一开始还是先写右边&nbsp;0~32767的范围,因为写出了右边后(32767),再将左边( -32768)加个符号,对左边的个位数情况(-0)做出处理,就可以啦。</p>
<p>首先0~32767 当前面为3276时,个位数只能匹配 0~7 :&nbsp;3276</p>
<p>0~32767 当前面为327时,后两位只能匹配 小于60的数字,也就是0~59,即个位数匹配 0~9,十位数匹配 0~5&nbsp;:&nbsp;327&nbsp; 或则&nbsp;327\\d</p>
<p>0~32767 当前面为32时,后三位只能匹配 小于700的数字,也就是0~699,即个位数匹配 0~9,十位数匹配 0~9,百位数匹配 0~6&nbsp;:&nbsp;32&nbsp; 或则 32\\d\\d&nbsp; 也可以简写成 32\\d{2}&nbsp; <strong>花括号为前面一个字符重复的次数,这里也就是\\d必须要重复2次</strong>。下面是花括号的使用讲解。</p>
<table><tbody><tr><td>{n}</td><td><p>n 是一个非负整数。匹配确定的 n 次。例如,&#39;o{2}&#39; 不能匹配 &quot;Bob&quot; 中的 &#39;o&#39;,但是能匹配 &quot;food&quot; 中的两个 o。</p></td></tr><tr><td>{n,}</td><td><p>n 是一个非负整数。至少匹配n 次。例如,&#39;o{2,}&#39; 不能匹配 &quot;Bob&quot; 中的 &#39;o&#39;,但能匹配 &quot;foooood&quot; 中的所有 o。&#39;o{1,}&#39; 等价于 &#39;o+&#39;。&#39;o{0,}&#39; 则等价于 &#39;o*&#39;。</p></td></tr><tr><td>{n,m}</td><td><p>m 和 n 均为非负整数,其中n &lt;= m。最少匹配 n 次且最多匹配 m 次。例如,&quot;o{1,3}&quot; 将匹配 &quot;fooooood&quot; 中的前三个 o。&#39;o{0,1}&#39; 等价于 &#39;o?&#39;。请注意在逗号和两个数之间不能有空格。</p></td></tr></tbody></table>
<p>0~32767 当前面为3时,后四位只能匹配 小于2000的数字,也就是0~1999,即个位数匹配 0~9,十位数匹配 0~9,百位数匹配 0~9,千位数匹配0~1&nbsp;:&nbsp;3&nbsp; 或则 3\\d\\d\\d&nbsp; 也可以简写成 3\\d{3}。</p>
<p>0~32767 当存在5位数字,也就是输入数字为万位的时候,那么现在万位只能存在1~2(因为3已经在前面匹配过来,这里不需要继续匹配3的情况了),后四位就可以全匹配0~9,因为只要存在5个数,且万位数字又是1~2的范围内,所以个位、十位、百位、千位再大也不可能会超过30000的&nbsp;,即个位数匹配 0~9,十位数匹配 0~9,百位数匹配 0~9,千位数匹配0~9&nbsp;:&nbsp;&nbsp; 或则 \\d\\d\\d\\d&nbsp; 也可以简写成 \\d{4}。</p>
<p>0~32767 当存在4位数字,也就是输入数字为千位的时候,那么现在千位就能存在1~9,后面的百位、十位、个位的取值情况可以为0~9,即千位存在\\d\\d\\d,百位存在\\d\\d,十位位存在\\d,(这里个位为一个数字的情况,留到最后处理)这么组合下来就是&nbsp;\\d\\d\\d|\\d\\d|\\d,这样匹配没有问题,但是展示不太好,所以这里用到花括号简写为:&nbsp; \\d{1,3}&nbsp; 花括号1~3的意思就是匹配\\d至少一次,最多3次。</p>
<p>0~32767 当只存在1位数字,也就是只输出个位的时候,即\\d或者。</p>
<p>所以结合上面的匹配结果 &nbsp;0~32767的匹配公式为</p>
<div class="jb51code"><pre class="brush:js;">"^(3276|327\\d|32\\d{2}|3\\d{3}|\\d{4}|\\d{1,3}|\\d)$"</pre></div>
<p>那么同理-32768 ~ -1,因为不存在-0的情况,而前面0~32767已经匹配了0,所以此处只匹配到-1。即:</p>
<div class="jb51code"><pre class="brush:js;">"^-(3276|327\\d|32\\d{2}|3\\d{3}|\\d{4}|\\d{0,3})$"</pre></div>
<p>那么-32768 ~ 32767的匹配公式,也就是int16的匹配公式为</p>
<div class="jb51code"><pre class="brush:js;">"^(-(3276|327\\d|32\\d{2}|3\\d{3}|\\d{4}|\\d{0,3})|(3276|327\\d|32\\d{2}|3\\d{3}|\\d{4}|\\d{1,3}|\\d))$"</pre></div>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202210/2022100910465214.png" /></p>
<p>同理,int32(-2147483648 ~ 2147483647)、int64(-9223372036854775808 ~ 9223372036854775807)也可以按照这样的方式匹配,当然这只是我简单看了一下后的理解,可能存在还有更简单的方法,欢迎各位大佬赐教。</p>
<p class="maodian"><a name="_label2"></a></p><h2>总结</h2>
頁: [1]
查看完整版本: 如何使用正则表达式对输入数字进行匹配详解