1. 程式人生 > >java利用正則表示式提取字串中的整數和小數部分

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