java利用正则表达式提取字符串中的整数和小数部分

最近开发遇到一个新的东西,就是前端传过来一个字符串,需要将里面的数字提取出来,倒腾了一天,最后还是没有倒腾出来,最后还是借鉴大佬的方法。记录一下。

首先是前端传来的字符串“小明通过扫码向你付款100000.566元”其中昵称和金额不是固定的,其他是固定的。
于是便考虑使用“通过扫码向你付款”作为分割的标志:

		String string = "小明通过扫码向你付款通过扫码向你付款1.12元";
		String str = "通过扫码向你付款";
		String[] list = string.split(str);
		for(String res : list){
            System.out.println(res);
        }

使用String的split方法可以将原字符串依据str分割成多个字符串,其中源字符串中的str被替换成空的“”

打印出来是:

小明

1.12

然后可以直接对数组list的最后一项进行操作了,这里才是我需要的金额数据。然而问题就来了。。。。

		String strLast = list[l-1];
		System.out.println("strLast:" + strLast);   //1.12元,汉字占用4个字节,所以下面采用-4操作
		String str2 = strLast.substring(0, str.length()-4);
		System.out.println("金额:" + str2);

刚开始我是这么写的,是我的疏忽写错了的,然后运行一下,结果竟然也出来了,但是仔细一看,这里面有个问题,可以看到在使用截取最后一个字符串的时候,使用的是str,而不是strLast,很神奇吧。。。。。

按照正常的逻辑,应该是使用strLast操作截取的,但是写strLast之后,截取的金额只有整数位了,小数位丢失了,但是让我很费解的是,使用str.length()-4这个,竟然能正确的截取出来金额。。。。。。截取金额已经跟这个过滤字符串str已经没有任何关系了。。。。。。。

没找到原因,那就先这么用着吧,毕竟安卓那边要调试借口了,就先这样用着了。。。。。。。

今天早上来了之后,感觉那样写肯定是有问题的,于是我便换个数据测,之前的金额都是用xx.xx测的,都没问题,于是直接上10000000,果然出错了,只能输出四位:1000

昨天查资料的时候查到关于正则表达式的,但是只能识别整数,没看到小数的,然后今天偶然翻到大佬自己写的提取数据的方法,看完之后,发现这个就是我想实现的效果,于是开始复制粘贴。。。。。。

下面贴出来具体的代码:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class NumberUtil {
	public static void main(String[] args) {
		String string = "10000.5689元";
		System.out.println(getNumber(string));
	}
	
	public static String getNumber(String str){
		// 控制正则表达式的匹配行为的参数(小数)
        Pattern p = Pattern.compile("(\\d+\\.\\d+)");
        //Matcher类的构造方法也是私有的,不能随意创建,只能通过Pattern.matcher(CharSequence input)方法得到该类的实例. 
        Matcher m = p.matcher(str);
        //m.find用来判断该字符串中是否含有与"(\\d+\\.\\d+)"相匹配的子串
        if (m.find()) {
            //如果有相匹配的,则判断是否为null操作
            //group()中的参数:0表示匹配整个正则,1表示匹配第一个括号的正则,2表示匹配第二个正则,在这只有一个括号,即1和0是一样的
            str = m.group(1) == null ? "" : m.group(1);
        } else {
            //如果匹配不到小数,就进行整数匹配
            p = Pattern.compile("(\\d+)");
            m = p.matcher(str);
            if (m.find()) {
                //如果有整数相匹配
                str = m.group(1) == null ? "" : m.group(1);
            } else {
                //如果没有小数和整数相匹配,即字符串中没有整数和小数,就设为空
                str = "";
            }
        }
        return str;
	}
}

这是第一个版本,对于我使用来说足够用了,因为我截取之后,对“xxxx元”操作提取金额数据,里面只有一个数字串,和一个中文汉字。

升级版的代码是可以提取一个字符串中的多个数值段:
比如字符串小明hhhh100通过扫码向你付款通过扫码向你付款通过扫码向你付款1.12和100000hh2.50元
输出数据:100,1.12,100000,2.50

	public static String getNumber(String str){
		//先判断有没有整数,如果没有整数那就肯定就没有小数
        Pattern p = Pattern.compile("(\\d+)");
        Matcher m = p.matcher(str);
        String result = "";
        if (m.find()) {
            Map<Integer, String> map = new TreeMap<>();
            Pattern p2 = Pattern.compile("(\\d+\\.\\d+)");
            m = p2.matcher(str);
            //遍历小数部分
            while (m.find()) {
                result = m.group(1) == null ? "" : m.group(1);
                int i = str.indexOf(result);
                String s = str.substring(i, i + result.length());
                map.put(i, s);
                //排除小数的整数部分和另一个整数相同的情况下,寻找整数位置出现错误的可能,还有就是寻找重复的小数
                // 例子中是排除第二个345.56时第一个345.56产生干扰和寻找整数345的位置时,前面的小数345.56会干扰
                str = str.substring(0, i) + str.substring(i + result.length());
            }
            //遍历整数
            Pattern p3 = Pattern.compile("(\\d+)");
            m = p3.matcher(str);
            while (m.find()) {
                result = m.group(1) == null ? "" : m.group(1);
                int i = str.indexOf(result);
                //排除jia567.23.23在第一轮过滤之后留下来的jia.23对整数23产生干扰
                if (String.valueOf(str.charAt(i - 1)).equals(".")) {
                    //将这个字符串删除
                    str = str.substring(0, i - 1) + str.substring(i + result.length());
                    continue;
                }
                String s = str.substring(i, i + result.length());
                map.put(i, s);
                str = str.substring(0, i) + str.substring(i + result.length());
            }
            result = "";
            for (Map.Entry<Integer, String> e : map.entrySet()) {
                result += e.getValue() + ",";
            }
            result = result.substring(0, result.length()-1);
        } else {
            result = "";
        }
        System.out.println(result);
        //String[] split = result.split(",");
        //String resultRtr = split[split.length-1];
        //return resultRtr;
	}

借鉴大佬的博客的出处:https://blog.csdn.net/tuesdayma/article/details/76412800

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值