Java開發筆記(三十七)利用正則串分割字元串

来源:https://www.cnblogs.com/pinlantu/archive/2018/12/15/10125236.html
-Advertisement-
Play Games

前面介紹了處理字元串的常用方法,還有一種分割字元串的場景也很常見,也就是按照某個規則將字元串切割為若幹子串。分割規則通常是指定某個分隔符,根據字元串內部的分隔符將字元串進行分割,例如逗號、空格等等都可以作為字元串的分隔符。正好String類型提供了split方法用於切割字元串,只要字元串變數調用sp ...


前面介紹了處理字元串的常用方法,還有一種分割字元串的場景也很常見,也就是按照某個規則將字元串切割為若幹子串。分割規則通常是指定某個分隔符,根據字元串內部的分隔符將字元串進行分割,例如逗號、空格等等都可以作為字元串的分隔符。正好String類型提供了split方法用於切割字元串,只要字元串變數調用split方法,並把分隔符作為輸入參數,該方法即可返回分割好的字元串數組。
下麵的split調用代碼例子演示瞭如何按照逗號和空格切割字元串:

	// 通過逗號分割字元串
	private static void splitByComma() {
		String commaStr = "123,456,789";
		// 利用split方法指定按照逗號切割字元串
		String[] commaArray = commaStr.split(",");
		for (String item : commaArray) {
			System.out.println("comma item = "+item);
		}
	}

	// 通過空格分割字元串
	private static void splitBySpace() {
		String spaceStr = "123 456 789";
		// 利用split方法指定按照空格切割字元串
		String[] spaceArray = spaceStr.split(" ");
		for (String item : spaceArray) {
			System.out.println("space item = "+item);
		}
	}

除了逗號和空格以外,點號和豎線也常常用來分隔字元串,但是對於點號和豎線,split方法的調用代碼不會得到預期的結果。相反,split(".")無法得到分割後的字元串數組,也就是說結果的字元串數組為空;而split("|")分割得到的字元串數組,每個數組元素只有一個字元,其結果類似於toCharArray。究其原因,緣於split方法的輸入參數理應是個正則串,並非普通的分隔字元。由於點號和豎線都是正則串的保留字元,因此無法直接在正則串中填寫,必須進行轉義處理方可。如同回車符和換行符在普通字元串中通過首碼的反斜桿轉義那樣(回車符對應\r,換行符對應\n),正則字元串通過在原字元前面添加兩個反斜桿來轉義,像點號字元在正則串中對應的轉義符為“\\.”,而豎線在正則串中對應的轉義符為“\\|”。經過轉移處理之後,通過點號和豎線切割字元串的正確代碼寫法如下所示:

	// 通過點號分割字元串
	private static void splitByDot() {
		String dotStr = "123.456.789";
		// split(".")無法得到分割後的字元串數組
		//String[] dotArray = dotStr.split(".");
		// 點號是正則串的保留字元,需要進行轉義(在點號前面加兩個反斜桿)
		String[] dotArray = dotStr.split("\\.");
		for (String item : dotArray) {
			System.out.println("dot item = "+item);
		}
	}

	// 通過豎線分割字元串
	private static void splitByLine() {
		String lineStr = "123|456|789";
		// split("|")分割得到的字元串數組,每個數組元素只有一個字元,類似於toCharArray的結果
		//String[] lineArray = lineStr.split("|");
		// 豎線是正則串的保留字元,需要進行轉義(在豎線前面加兩個反斜桿)
		String[] lineArray = lineStr.split("\\|");
		for (String item : lineArray) {
			System.out.println("line item = "+item);
		}
	}

豎線符號之所以被定為正則串的保留字元,是因為它在正則表達式里起到了“或”的判斷作用,例如正則串“,| ”表示逗號和空格都是滿足條件的分隔符;一個字元串如果同時包含一個逗號和一個空格,那麼按照“,| ”切割的結果將是長度為3的字元串數組;也就是說,原始串被逗號分割一次後又被空格分割一次,這樣一共分割兩次最終得到了三個子串。下麵的代碼演示了使用正則串“,| ”切割字元串的效果:

	// 利用豎線同時指定多個串來分割字元串
	private static void splitByMixture() {
		String mixtureStr = "123,456 789";
		// 正則串里的豎線表示“或”,豎線左邊和右邊的字元都可以用來分割字元串
		String[] mixtureArray = mixtureStr.split(",| ");
		for (String item : mixtureArray) {
			System.out.println("mixture item = "+item);
		}
	}

 

當然,正則串中的保留字元不僅包括點號和豎線,還包括好些常見的符號,比如加號(+)、星號(*)、橫線(-),在正則串中均需進行轉義。其中加號的正則轉義符為“\\+”,星號的正則轉義符為“\\*”,橫線的正則轉義符為“\\-”。這麼估摸下,加減乘除的四則運算符號,只有除法的斜桿符(/)、取餘數的百分號(%)無需轉義處理。倘若有個字元串,要求以四則運算的五個符號進行切割,則需通過豎線把這幾個轉義後的字元加以連接,構成形如“\\+|\\*|\\-|/|%”的正則串。於是按照加減乘除符號切割字元串的代碼就變為下麵這樣:

	// 通過算術的加減乘除符號來分割字元串
	private static void splitByArith() {
		String arithStr = "123+456*789-123/456%789";
		// 正則串里的加號、星號、橫線都要轉義,加減乘除符號之間通過豎線隔開
		String[] arithArray = arithStr.split("\\+|\\*|\\-|/|%");
		for (String item : arithArray) {
			System.out.println("arith item = "+item);
		}
	}

 

分割用的正則串,不單單是一個個字元,還支持好幾個字元組成的字元串。譬如“(1)”、“(2)”、“(3)”都可以作為分隔串,註意圓括弧內部的數字可以是0到9,如此一來,從“(0)”到“(9)”的分隔串合集豈不是要寫成以下這般:“(0)|(1)|(2)|(3)|(4)|(5)|(6)|(7)|(8)|(9)”?然而以上正則串的寫法有兩個錯誤:
1、圓括弧也是正則表達式的保留字元,所以不能直接在正則串中書寫“(”和“)”,而必須寫成轉義形式“\\(”和”“\\)”。
2、作為保留字元的圓括弧,其作用類似數值計算之時的圓括弧,都是通過圓括弧把括弧內外的運算區分開。而豎線符號“|”的或運算優先順序不如圓括弧,因此每逢複雜一點的或運算,應當把圓括弧放在整個邏輯運算式子的外面。
綜合以上兩點,修正之後的正則串應該改成下列形式:“\\((0|1|2|3|4|5|6|7|8|9)\\)”。可是該式子的豎線太多,意思僅僅是獲取0到9之間的某個數字之一,針對這種情況,正則表達式引入了另外一種簡化的寫法,即通過方括弧包裹0123456789,形如“\\([0123456789]\\)”,同樣指代0到9之間的某個數字,從而省略了若幹個豎線。進一步說,日常生活中0到9,常常寫做“0-9”,於是對應更簡單的正則串“\\([0-9]\\)”。
其實0到9正好涵蓋了所有的一位數字,對於一位數字而言,正則表達式提供了專門的表達式“\\d{1}”。式子前面的“\\d”代表某個數字,式子後面的“{1}”代表字元數量是1位。推而廣之,“\\d{2}”表示兩位數字,“\\d{3}”表示三位數字,等等。像這個正則例子只有一位數字,甚至尾巴的“{1}”都可以去掉,因為“\\d”預設就是一位數字。
一口氣介紹了許多種從0到9的正則表達串,接下來不妨逐一驗證這些正則串是否有效,驗證用的代碼例子如下所示:

	// 通過圓括弧及其內部數字來分割字元串
	private static void splitByBracket() {
		String bracketStr = "(1)123;(2)456;(3)789;";
		// 圓括弧也是正則串的保留字元,0到9這九個數字使用豎線隔開
		//String[] bracketArray = bracketStr.split("\\((0|1|2|3|4|5|6|7|8|9)\\)");
		// 利用方括弧聚集一群字元,表示這些字元之間是“或”的關係,故而可省略豎線
		//String[] bracketArray = bracketStr.split("\\([0123456789]\\)");
		// 連續的數字可使用橫線連接首尾數字,例如“0-9”表示從0到9之間的所有數字
		//String[] bracketArray = bracketStr.split("\\([0-9]\\)");
		// 利用“\\d”即可表達0到9的數字,後面的{1}表示1位數字,依此類推{3}表示三位數字
		//String[] bracketArray = bracketStr.split("\\(\\d{1}\\)");
		// “\\d”預設就是1位數字,此時後面的{1}可直接略去
		String[] bracketArray = bracketStr.split("\\(\\d\\)");
		for (String item : bracketArray) {
			System.out.println("bracket item = "+item);
		}
	}

 

上述的幾種正則串,只能表達從“(0)”到“(9)”的分隔串,然而圓括弧內部還可能是兩位數字或者三位數字,比如“(10)”、“(12)”、“(001)”這樣。對於數字位數不固定的情況,可以把“\\d”改為“\\d+”,末尾多出來的加號,表示前面的字元允許有一位,也允許有多位。此時正則串添加了加號的字元串切割代碼見下:

	// 通過特殊符號的加號來分割字元串
	private static void splitWithPlus() {
		String bracketStr = "(1)123;(2)456;(13)789;";
		// 正則串里的加號表示可以有1到多個前面的字元
		String[] bracketArray = bracketStr.split("\\(\\d+\\)");
		for (String item : bracketArray) {
			System.out.println("plus item = "+item);
		}
	}

 

上面說的位數不固定,畢竟至少還有一位。假設現在某個字元不但位數不確定,甚至還可能沒有該字元(位數為0),採用寫法“\\d+”就無法奏效了。要想滿足位數可有可無的情況,需將末尾的加號換成星號,也就是改成“\\d*”,此時改用星號的字元串切割代碼變為下麵這般:

	// 通過特殊符號的星號來分割字元串
	private static void splitWithStar() {
		String bracketStr = "()123;(2)456;(13)789;";
		// 正則串里的星號表示可以有0到多個前面的字元
		String[] bracketArray = bracketStr.split("\\(\\d*\\)");
		for (String item : bracketArray) {
			System.out.println("star item = "+item);
		}
	}

 

到目前位置,分隔符還僅限於標點和數字,如果引入英文字母作為分隔串,又該如何書寫呢?註意英文字母區分大小寫,因而使用“a-z”表示所有的小寫字母,使用“A-Z”表示所有的大寫字母。如果採納“(a)”、“(B)”、“(c)”這種大小寫混合的分隔串,就得通過正則串“\\([a-zA-Z]\\)”來表達,對應的字元串切割代碼如下所示:

	// 通過大小寫字母來分割字元串
	private static void splitWithLetter() {
		String bracketStr = "(a)123;(B)456;(c)789;";
		// 在正則串中表達小寫字母和大寫字母
		String[] bracketArray = bracketStr.split("\\([a-zA-Z]\\)");
		for (String item : bracketArray) {
			System.out.println("letter item = "+item);
		}
	}

 

現在有個麻煩的業務場景,圓括弧內部不但可能是數字和字母,還可能是其它標點符號,這下難不成把眾多標點符號一個個羅列出來?要知道標點符號可沒有“0-9”、“a-z”、“A-Z”的簡單寫法噢。不過這難不倒強大的正則表達式,因為點號作為正則的保留字元,它代表了除回車\r和換行\n以外的其它字元,所以使用“\\(.\\)”即可表達符合要求的任意字元了,當然是被圓括弧包裹著的、除了回車\r和換行\n以外的任意字元。下麵便是匹配前述場景的字元串切割代碼例子:

	// 通過特殊符號的點號來分割字元串
	private static void splitWithDot() {
		String bracketStr = "(1)123;(B)456;(%)789;";
		// 正則串里的點號表示除了回車\r和換行\n以外的其它字元
		String[] bracketArray = bracketStr.split("\\(.\\)");
		for (String item : bracketArray) {
			System.out.println("dot item = "+item);
		}
	}

  

更多Java技術文章參見《Java開發筆記(序)章節目錄



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 見名知其意,適配器可用於對多個不相容介面提供適配橋梁 介紹 適配器模式屬於結構型模式。在現實世界中,這個模式適用的較為廣泛,比如 DIY 一些電子產品,主要元器件提供的是標準介面,那麼無論我們購買什麼品牌的元器件,最終都能組裝起來正常運行。 類圖描述 由上圖可知,我們通過定義 IAdvancedMe ...
  • 面向對象設計原則 概述 對於面向對象軟體系統的設計而言,在支持可維護性的同時,提高系統的可復用性是一個至關重要的問題,如何同時提高一個軟體系統的可維護性和可復用性是面向對象設計需要解決的核心問題之一。在面向對象設計中,可維護性的復用是以設計原則為基礎的。每一個原則都蘊含一些面向對象設計的思想,可以從 ...
  • 環境:C++ 11 + win10 IDE:Clion 2018.3 AVL平衡樹是在BST二叉查找樹的基礎上添加了平衡機制。 我們把平衡的BST認為是任一節點的左子樹和右子樹的高度差為-1,0,1中的一種情況,即不存在相差兩層及以上。 所謂平衡機制就是BST在理想情況下搜索複雜度是o(logn) ...
  • eclipse項目過多怎麼方便管理呢? 可以使用workset來進行管理。這裡的workset跟.net 也就是visual studio中的項目解決方法類似,可以將項目、類庫進行分開管理。 可以點擊project explorer中小三角進行操作 然後在彈出界面中進行操作 ...
  • 前言 with語句的使用給我們帶來了很多的便利,最常用的可能就是關閉一個文件,釋放一把鎖。 既然with語句這麼好用,那我也想讓我自己寫的代碼也能夠使用with語句,該怎麼實現? 下麵具體介紹怎樣實現一個自己的with語句 使用類實現 要想使用with語句,那就要遵循with語句的使用規矩,也就是上 ...
  • 切片實例 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38 ...
  • 一、安裝nginx https://yq.aliyun.com/articles/101144?spm=5176.10695662.1996646101.searchclickresult.70af967bColksb 二、nginx.conf文件配置 /usr/local/nginx/conf/c ...
  • 原創作品,可以轉載,但是請標註出處地址: "https://www.cnblogs.com/V1haoge/p/10125279.html" SpringBoot整合MyBatis plus 步驟 第一步:添加必要的依賴 第一種是在已存在MyBatis的情況下,直接添加mybatis plus包即可 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...