当前位置: 首页 > 科技观察

如何实现数值验证的算法

时间:2023-03-21 13:14:15 科技观察

给定一个字符串,如何判断它是否为数值类型?例如:字符串+100、5e2、-123、3.1416、-1E-16都是表示值的,是数值类型,但是12e、1a3.14、1.2.3、+-5、12e+5.4是不是。本文将带你实现这个判断算法。欢迎有兴趣的开发者阅读本文。实现思路首先看一下值的定义规则:表示值的字符串遵循模式A[.[B]][e|EC]或.B[e|EC],其中:A为整数部分值和B紧随小数点后是值的小数部分C后跟e或E是值的指数部分。十进制的值可能没有整数部分,例如:十进制的.123等于0.123。因此,A部分不是必需的。如果一个数字没有整数部分,它的小数部分不能为空。上面提到的A和C都是0到9的数字串,可以+或-开头;B也是0到9的数字串,但前面不能有符号。我们以字符串123.45e+6为例,其中:123是它的整数部分A45是它的小数部分B+6是它的指数部分C在判断一个字符串是否符合上述模式时,首先尽可能多地扫描0到9的数字(开头可能有+或-),即前面模式中表示数字整数的A部分。如果遇到小数点,则开始扫描表示数值小数部分的B部分。如果遇到e或E,则开始扫描代表数值指数的C部分。整理完以上,我们可以罗列一下实现思路,如下:(1)在字符串后添加一个结束标记;(2)使用全局索引遍历字符串;(3)设计一个扫描无符号整数(字符串中0到9的数字)的函数,用于在数值模式下判断B部分;(4)设计一个函数,扫描0到9以+或-开头的数字,可以表示正数或负数(类似于一个整数可以有正负号),用于判断数值模式中的A和C部分;(5)从头扫描字符串,跳过第一个空格,扫描全局索引自增一次:调用scanwithSignedinteger函数扫描A部分如果字符串中包含小数点,调用scanunsignedinteger函数扫描partB如果字符串中包含E或e,调用scansignedinteger函数扫描partC(6)跳转(7)判断校验结果是否为真,全局索引是否递增到结束标志。下面我们以123.45e+6为例,画出上述流程的执行过程,如下图:一切准备就绪,可以执行代码了。接下来我们看一下代码实现。扫描无符号整数函数的代码如下:exportclassNumericalCheck{//指针索引privateindex=0;//扫描无符号整数privatescanUnsignedInteger(str:string):boolean{constbefore=this.index;while(str.charAt(this.index)>="0"&&str.charAt(this.index)<="9"){this.index++;}返回this.index>之前;}}scansignedinteger函数在None的基础上添加符号判断如下://scansignedintegerprivatescanInteger(str:string):boolean{//判断是否包含符号if(str.charAt(this.index)=="+"||str.charAt(this.index)=="-"){this.index++;}//扫描无符号整数returnthis.scanUnsignedInteger(str);}最后从头到尾遍历字符串,结合上面两个函数判断一个字符串是否为数字,代码如下:publicisNumber(numStr:string):boolean{if(numStr==null||numStr.length==0){返回false;}//添加结束标记numStr=numStr+"|";//跳过开头的空格while(numStr.charAt(this.index)==""){this.index++;}//扫描整数部分letnumeric=this.扫描整数(numStr);//有小数点,处理小数部分if(numStr.charAt(this.index)=="."){this.index++;//只要小数点两边都是数字,就用||数字=this.scanUnsignedInteger(numStr)||数字;}//有e||E、处理索引部分if(numStr.charAt(this.index)=="E"||numStr.charAt(this.index)=="e"){this.index++;//e||E两边都是数字,所以用&&numeric=numeric&&this.scanInteger(numStr);}//跳过尾随空格while(numStr.charAt(this.index)==""){this.index++;}constcheckResult=numeric&&numStr.charAt(this.index)=="|";//重置指针索引this.index=0;返回检查结果;}完整代码请移步:NumericalCheck.ts测试用例接下来我们举几个例子,带入到上面的代码中,看看能否正确执行,如下图:letstr="123.45e+6";constnumericalCheck=newNumericalCheck();letcheckResult=numericalCheck.isNumber(str);printCheckResult();str=".12e1";checkResult=numericalCheck.isNumber(str);printCheckResult();str="12e";checkResult=numericalCheck.isNumber(str);printCheckResult();str="1.2.3";checkResult=numericalCheck.isNumber(str);printCheckResult();functionprintCheckResult(){console.log(`字符串${str}是否为数字校验结果为:${checkResult}`));}执行结果如下:示例代码本文提到的完整版代码请移步:NumericalCheck.tsnumericalCheck-test.ts