小数点后保留2位小数的正则表达式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tel13259437538/article/details/80752308

Write By Monkeyfly

以下内容均为原创,如需转载请注明出处。

前提

  • 今天同事问我,这个正则表达式是什么意思?(如下所示)

^(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,2})?$

  • 我说目前我也不知道它代表什么,那要看你的使用场景了,一时半会也看不出来,我得分析一下。
  • 他说,要求保留两位小数。这是我网上百度的用法,你看一下对不对?
  • 于是,我就去求证了。

分析

要看明白正则表达式,首先就要从语法层面进行分析,把每一部分都了解清楚,弄明白,必须知道每一部分匹配的是什么,随后整个表达式的意思也就迎刃而解了。

^(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,2})?$

(1)首先从写法上可以看出,使用了显式定义正则表达式的语法,因为其中存在对字符串"\"(反斜杠)的转义。

  • 普及一下:正则表达式的定义共有2种方式:显示定义隐式定义
/*\d是正则表达式中的元字符,用于匹配数字,相当于[0-9],所以[0-9]也可以写成\d*/
var myregex = new RegExp("[0-9]");    //显式定义
var myregex = /[0-9]/;    //隐式定义
  • 对两种定义方式的解释说明:
    这里写图片描述
    (2)其次,我们把正则表达式拆分开,以分组的形式来观察,问题就简单多了。因为复杂的正则表达式就是由许多子表达式构成的。
  • 此处涉及到正则表达的3个知识点:定位符限定符分组
    • 何谓定位符?即限定某些字符出现的位置。
      • 说明:^表示必须以什么字符开头;$表示必须以什么字符结尾。
    • 何谓限定符?即限定某个字符或某类字符出现的次数。
      • 说明:
        1. * 表示重复0次或更多次(任意次数);
        2. ?表示重复0次或1次(最多1次);
        3. {n}表示重复n次;
        4. {n,m}表示重复n-m次;
    • 何谓分组?分组又称为子表达式,即把一个正则表达式的全部或部分分成一个或多个组。
      • 语法:分组使用的字符为“(”“)”,即左括号和右括号。每一个子表达式都可以当做一个整体来处理。
  • 拆分的步骤:
//初始
^(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,2})?$
//为了简化操作,方便观察,在这里把字符串的转义都去掉。
^(([1-9]{1}\d*)|([0]{1}))(\.(\d){0,2})?$
即:(([1-9]{1}\d*)|([0]{1}))(\.(\d){0,2})
//第一步:先分组,不管定位符和限定符。总共可分为两大组。
(([1-9]{1}\d*)|([0]{1}))//第一大组:整数部分
(\.(\d){0,2})//第二大组:小数部分
//第二步:继续分组,将第一大组(整数部分)继续拆分,可分为3部分。
([1-9]{1}\d*)//第一部分
| //第二部分
([0]{1})//第三部分

知识点说明:
[...]是正则表达式中的元字符它会匹配方括号中的所有字符。
|是正则表达式中的选择符。简单来说就是:用于二选一即选择2个选项之中的任意一个,选他或选她。

第二步分析:
因此,在第二步中,第一部分和第三部分的子表达式,这两部分只要满足任何一个部分都可以匹配的上。

注:这也就说明了整数部分的两种情况:首位是0和首位不是0。即0.1213.145.21

  • 先来看第一部分中的内容,即第一种情况,首位不为0([1-9]{1}\d*)
    • 可以看出,第一部分由两个模块组成,即[1-9]{1}\d*
      (1)[1-9]{1}表示1-9之间的数字只出现一次,即保证了该数的首位不是0,总之是大于0的数。
      (2)\d*表示0-9之间的数字可以出现任意次,即0次或更多次。出现0次说明是一位整数。出现更多次就是多位整数。
  • 再来看第三部分中的内容,即第二种情况,首位为0([0]{1})【一个字符没必要使用[元字符,直接写0就行,即(0{1})
    • 这个就比较简单了,表示数字0只能出现一次,即首位只能是0,而且只能有一个0

总结:第一大组匹配了整数部分的情况,大于0的数还是小于1的数

(\.(\d){0,2})//第二大组:小数部分
//第三步:继续分组,将第二大组(小数部分)继续拆分,可分为3部分。
\.      //第一部分
(\d)    //第二部分
{0,2}   //第三部分

知识点说明:
.(点)是正则表达式中的元字符它会匹配除了换行符以外的任意字符

注:由于.(点)是元字符,所以,如果想要匹配字面意义上的点时(此处需要匹配小数点),需要使用转义字符\(反斜杠)将它进行转义,即\.

第三步分析:

  • 第一部分:\.表示匹配小数点。
  • 第二部分:(\d)表示匹配数字0-9。【此处可以不用分组符,用了多此一举】
  • 第三部分:{0,2}表示将前面的字符重复0-2次,即重复的次数不确定,可能重复0次,可能重复1次,也可能重复2次。
  • 其实,二三部分应该放在一块分析,即\d{0,2},表示:0个数字、1个数字或者2个数字。

总结:第二大组匹配了小数点后所保留的位数,分别是小数点后保留0位小数(即正整数)、小数点后保留1位小数或者小数点后保留2位小数。

注:如果要匹配小数点后保留2位小数,则只需要改一下限定符即可。\.\d{2}

至此为止,我们已经将正则表达式拆分完毕,现在就需要将它们完整的分析一下。

(([1-9]{1}\d*)|(0{1}))(\.\d{0,2})
  • 完整分析:
/*1、先加上限定符?(问号)【它表示前面紧跟的字符,即(\.\d{0,2})这个整体,重复0次或1次(最多1次)】*/
(([1-9]{1}\d*)|(0{1}))(\.\d{0,2})?

//如果(\.\d{0,2})不存在,表示该数为自然数(指非负整数,即正整数与0的集合),无小数部分。
//如果(\.\d{0,2})存在,表示该数为小数。
/*如果是小数的话,按照大小来分,存在两种情况:
**(1)可能是大于0的小数;即([1-9]{1}\d*)
**(2)也可能是小于1的小数;即(0{1})
*/
/*如果是小数的话,按照位数来分,存在3种情况:
**(1)无小数位数,为整数;即(\.\d{0,2})重复0次,相当于没有它
**(2)有小数位数,为小数;即(\.\d{0,2})重复1次
**   小数的位数又分为三种情况:{0,2}相当于是{0},{1},{2}的集合,它们之间是“或”的关系
**      小数点后保留0位小数;即\.\d{0}
**      小数点后保留1位小数;即\.\d{1}
**      小数点后保留2位小数;即\.\d{2}
*/

在这里普及一下整数的知识:
我们以0为界限,将整数分为3大类:

  • 正整数。即大于0的整数,如:1,2,3,…
  • 00既不是正整数,也不是负整数(0是整数)。
  • 负整数。即小于0的整数,如:-1,-2,-3,…
/*2、最后再加上限定开始和结束位置的限定符,^和$。*/
^(([1-9]{1}\d*)|(0{1}))(\.\d{0,2})?$

//这就表示了,它必须以数字开头和结尾。限定了它必须是一个数字,而不能包含其他的字符。

结果

^(([1-9]{1}\d*)|(0{1}))(\.\d{0,2})?$就表示了小数点后可以保留0位、1位、或2位小数。

如果我们要求小数点后只能保留2位小数,则修改表示小数点后面数字的重复次数(即位数)的限定符{},直接将{0,2}改为{2},然后去掉限定符?即可。去掉了 ? 就代表该数不可能是整数,一定是小数。

最终的正则表达式:^(([1-9]{1}\d*)|(0{1}))(\.\d{2})$

测试过程:

如下图所示

隐式定义:↓
这里写图片描述
显式定义:↑

猜你喜欢

转载自blog.csdn.net/tel13259437538/article/details/80752308