首页 > 编程语言 >java利用正则表达式提取字符串中的整数和小数部分

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

时间:2022-12-02 17:36:29浏览次数:43  
标签:java String 正则表达式 Pattern 整数 substring result str 小数


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

首先是前端传来的字符串​​“小明通过扫码向你付款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;
}

 

标签:java,String,正则表达式,Pattern,整数,substring,result,str,小数
From: https://blog.51cto.com/linmengmeng/5907331

相关文章