如何写正则表达式校验【整数】和【浮点数】的正确格式

题目

分别编写名字为TestPackageCalss和MyException类,实现一下功能:在控制台串中输入一串字符,并判断,如果是整数字符串,则转换成Ingeger对象,如果是浮点数字符串则转换成Double对象,并格式化为 $#....#.##(不用四舍五入输出进度到小数点后面两位),如果是非数字,则抛出显式抛出自定义异常类MyException,异常信息是“输入了数据无法实现数字格式转换"。

(作业题,描述不太严谨,按照大概意思来即可)

说明

这个作业题不是重点,本博客重点是:以该题目为切入点,如何去写校验【正整数】和【浮点数】格式的正则表达式。正则表达式一般去网上找就行了,但掌握正则表达式的基础知识并会写简单的正则表达式也比较重要。

分析

1.整数

问:如何理解正确的整数格式?

举例:0,-1235,102340。。。这个不好说,只能靠意会

问:什么是正确的整数格式?

举例:000,-0,+0,03524。。。显然一般来说,正确的整数格式是:不会有前导0的

 

先来看看网上找到的一个校验整数的正则表达式

String regex="^-?\\d+$";

还算比较简单吧。很容易看出来,这个正则表达式会错判有前导0的情况,会认为000,-0,+0,03524...这些是正确。

仅仅从作业题来看,Java种的 Integer.valueOf(str) 的 str 是允许前导0的,str 有前导0,该函数也能成功转换,并不会抛出异常。那么如果只是为了做这个作业题,这个正则表达式够用了。

假设OJ上有这么一题:

题目

      请编写程序,判断给出的字符串是否符合正确的整数格式。

      正确的整数格式:0,-1235,102340。。。

      不正确的整数格式:000,-0,+0,03524。。

输入格式

      每一行输入一个字符串,输入若干行。

输出格式

      符合格式输出“yes”,否则输出“no”。

C/C++肯定是可以做的,但不好做。对于学习C/C++的同学来说,这是一道不错的考察字符串的题目。

 

铺垫了这么多。进入正题。

正确的整数格式分两种情况来考虑

(1)0。为什么0如此特殊以至于单独作为一种情况?因为防止这样的数据:-0,000,00。。。

(2)非0。有没有负号都是可以的,但第一位数字必定是[1-9],因为不能有前导0!随后的数位可以是[0-9]。

总结出规律,那么这个正则表达式就非常简单了

String regex="(-?[1-9]\\d*)|0";

 

2.浮点数

显然校验浮点数比校验整数复杂得多。考虑的情况很多,可能会有点乱。所以思考的时候注重角度。

 

明确一点:小数点只是正确的浮点数的格式的一个显著特征,一个符合正确格式的浮点数不一定要有小数点

例如:1.0符合浮点数的格式,1也认为是正确的浮点数格式。

 可以这样认为:符合整数格式的字符串都符合浮点数格式。

 

正确的浮点数格式,分两个角度来考虑

(1)整数部分

浮点数的整数部分的校验能否直接搬上面校验整数的正则表达式?

不可以!为什么?

举例:-0.68是正确的浮点数格式,但如果搬上面的正则表达式校验其整数部分,-0.68会被认为有前导0而被错判!

整数部分的正则表达式:-?(0|[1-9]\\d*)

注意对比以下校验正整数的正则表达式,体会以下有什么不同?对比以下,可以看出0放在括号里面了,就是为了考虑到-0.68这种情况。

(2)小数部分

小数部分就非常简单了:(\\.\\d+)?

只要有小数点,后面必须有至少一位数字[0-9]。前面也说了,由于小数部分不是必须的,所以括起来然后加了个?

另外注意:由于“.”有特殊含义,在正则表达式表示:除了换行符以外的任意一个字符。故需要转义。

可以这样理解 “\\.”:① “\\” 转义成 “\ ”;② “\.” 转义成 “.”

 

合起来得到

String regex="-?(0|[1-9]\\d*)(\\.\\d+)?";

但是

这个正则表达式仍会错判一个特殊情况:-0。 但它不会错判-00,-000。。。

想想为什么?

假如有小数部分,整数部分是可以允许是-0的。假如没有小数部分,整数部分不能是-0!正则表达式在校验整数部分时,还不知道后面有没有小数部分。

如何规避这种情况?

重新分类,重写正则表达式?

没必要。

若想在正则表达式中规避-0的情况,就要另外分类,将-0的情况单独分处理,但如果这样去干正则表达式就会变得冗长,
        且分类多了就容易重叠混乱,造成越想追求完美结果就越多bug的得不偿失。既然只有这一种特例,如果需要,在正则
        表达式外面特判即可。

代码

下面给出这个作业题的完整代码。

package theme4;

import java.text.DecimalFormat;
import java.util.Scanner;

/**
 * 分别编写名字为TestPackageCalss和MyException类,实现一下功能:在控制台串中输入一串字符,并判断,
 * 如果是整数字符串,则转换成Ingeger对象,如果是浮点数字符串则转换成Double对象,并格式化为 $#....#.##
 * (不用四舍五入输出进度到小数点后面两位,),如果是非数字,则抛出显式抛出自定义异常类MyException,
 * 异常信息是“输入了数据无法实现数字格式转换";
 */
public class TestPackageCalss {
	
	public static void main(String[] args) {
		//System.out.println(isDoubleFormat("-00"));
		testInteger();
		testDouble();
	}
	
	public static void testInteger()
	{
		System.out.println("请输入一个符合正确格式的整数字符串:");
		Scanner sc=new Scanner(System.in);
		String num=sc.nextLine();
		
		try {
			Integer intObj=strToInteger(num);
			System.out.println("成功将字符串转成Integer对象");
			System.out.println(intObj);
		} catch (MyException e) {
			System.out.println(e.getMessage());
		} finally {
			sc.close();
		}
	}
	
	public static void testDouble()
	{
		System.out.println("请输入一个符合正确格式的浮点数字符串:");
		Scanner sc=new Scanner(System.in);
		String num=sc.nextLine();
		
		try {
			Double doubleObj=strToDouble(num);
			String pattern="#.00";
			DecimalFormat myFormat=new DecimalFormat(pattern);
			System.out.println(myFormat.format(doubleObj));
		} catch (MyException e) {
			System.out.println(e.getMessage());
		} finally {
			sc.close();
		}
	}
	
	public static Integer strToInteger(String num) throws MyException
	{
		if(isIntegerFormat(num))
			return Integer.valueOf(num);
		else
			throw new MyException("字符串格式异常");
	}
	
	public static Double strToDouble(String num) throws MyException
	{
		if(isDoubleFormat(num))
			return Double.valueOf(num);
		else
			throw new MyException("字符串格式异常");
	}
	
	public static boolean isIntegerFormat(String num)
	{
		
		String regex="(-?[1-9]\\d*)|0"; 
		return num.matches(regex);
	}
	
	public static boolean isDoubleFormat(String num)
	{
		String regex="-?(0|[1-9]\\d*)(\\.\\d+)?";
		if(num.equals("-0"))
			return false;
		return num.matches(regex);
	}
	
	
}

 

package theme4;

/**
 * 自定义异常类
 * @author passerbyYSQ
 *
 */
public class MyException extends Exception {
	
	static final long serialVersionUID = -33875169934229948L;
	
	public MyException()
	{
		
	}
	
	public MyException(String msg)
	{
		super(msg);
	}
	
}

备注

自己写的正则表达式,没有严格测试过。如有错误,轻喷。。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值