給JAVA程式設計師的正則表達式一課

2021-01-07 蟲蟲搜奇

「不會正則表達式,就算寫遍代碼也嘛不是」。說到正則表達式,可能動態語言的碼農Perl,Python,JS甚至是Golang的開發人員可能都熟悉。對Java碼農來說,可能CURD手到擒來,Spring Stuts Hibernat耳聞能詳,但是說到Regex RE模式,可能熟練的少。

那麼,今天蟲蟲就來給廣大Java碼農來補補正則的課。

正則基礎

正則表達式(Regex,簡稱RE)是一種根據字符串集中的每個字符串的共同特徵來描述字符串集的方法。可用於搜索,編輯或處理文本和數據。簡單來說,正則表達式是幫助我們根據特定格式驗證或匹配字符串的方式。可以類比資料庫的SQL語言,sql是搜索數據,RE是搜索字符串。正則表達式和SQL語言是開發界的兩個偉大發明。

正則表達式可以用於:

驗證用戶的輸入。

搜索給定數據中的文本。(可在文本編輯器中使用)

編譯器中的解析器

語法突顯,數據包嗅探器等。

要全面了解Regex,我們要理解基本知識,下面我們分別介紹,示例中我們用到在線正則解析網站regex101。

基本量詞(*+?和{n})

正則表示式子中(各語言通用)中的數量詞由*,+.? 和{n}組成。

* 表示匹配零個或多個其先前模式的實例。例如,abc*表示文本必須與'ab'相匹配,後跟零個或多個'c',即文本可能沒有附加'c'並且文本也可能有一個或多個'c'。

+ 匹配其先前模式的一個或多個實例,例如abc+表示文本必須帶有「ab」,後跟一個或多個「c」。所以abc是您可以擁有的至少是正確的,而abcc也是正確的。

?匹配零個或一個出現的模式,例如abc?表示文本可以是abc或ab。

{n}表示與表達式中指定的確切數字(n)匹配。例如a{2}bc表示只能有兩個「a」,然後是一個「bc」和一個「c」。

{n,}至少匹配指定的數字。必須具有n個或更多個前面的表達式,例如ab{2,}c表示必須具有個a,然後是兩個或多個'b',然後是c。

{n,m}表示在模式的n和m(含)之間匹配。這意味著您可以在前至後之間出現m到m個事件。例如ab{2,5}c表示abbc,abbbc,abbbbc,abbbbbc都是正確的。

'.' 匹配所有非空格字符

運算符(|| [] ^和())

|表示「或」。表示與左側的表達式或右側的表達式匹配。例如abc|abd表示文本應為abc或abd。

[]表示文本應與尖括號中的任何字符匹配,例如a[bc]表示文本應為「a」,後跟「b」或「c」。

[0-9]%表示文本應為0到9之間的任何數字,後跟'%'

[a-zA-Z]表示匹配任何一個英文字母,只要介於az或AZ之間即可。

[abc]表示文本或字符串應為a或b或c。

在任何表達式中添加「^」會否定該表達式的含義,例如[^abc]表示匹配任何除abc外的任何字符。

()表示分組,分組後可以在後續反向引用。反向引用存儲與組匹配的字符串部分。可以使用符號$來引用特定的組。$1,$2…代表第一組1,第2組等。默認組為$0,表示字符串本身。例如,我們要刪除行中的所有空格。此示例的正則表達式為以下代碼片段:

private static String backReference(String text) {

String pattern = "(\\w+)([\\s])";

return text.replaceAll(pattern, "$1");

}

上面代碼中的正則表達式有2組:(\\w+)和([\\s])。表示字串是一系列單詞字符(\w+)後跟空格(\s+)。後面一句,我們用組1($1)來替換整個文本,這樣就刪除了空格。

注意:在Java中,我們需要用一個斜槓對字符類(\w和\s)進行轉義,否則會出現語法錯誤。

環視

環視一種排除模式的方法。因此,可以說只有在特定字符串之前沒有改符號時字符串才是有效的,反之亦然。例如,abc(?= d)只要與'd'相符,就會匹配'abc'。 「d」不會被匹配。這叫正向環視或者順序環視。

環視不是所有語言都支持,不是通用的語法,但是妙用可以解決很多問題,比如我們要解析HTML語法:

例如,對html中的一個連接

<a href=』ijz.me』> chognchong</a >

我們要取其中的連接地址

(?=')(.*(?='))

還有一個表示對順序環視的否定表達式,(?!pattern),表示如果'ab'後面沒有'c',則ab(?c)將匹配ab。

注意還有一個逆序環視,java中不支持,我們不介紹。

貪婪和懶惰

正則表達式中的的量詞默認貪婪的,匹配時候會儘可能多的匹配,這樣才能減少遞歸回溯搜索的次數,因而效率最高。例如,對於正則表達式a.+c,希望它表示文本應為'a',後跟一個或多個非空格字符。可能的匹配匹配項為「abcccd」,「abcc」或「abbc」,都是可以的,但是由於貪婪的緣故,它將把所有文本(abcccd abcc abbc)作為一個並返回「abcccd abcc abbc」作為一個結果,因為如果您注意到,第一個字符是「a」,然後是任何其他字符中的一個或多個,它現在以與a.+c完全匹配的c結尾。

為了修改默認的,貪婪模式,只需在量詞前面添加問號(?),這樣使量詞就會只要匹配最少匹配的模式。這時,ab.+?c就會單獨匹配各個字串,而不是整個字符串。

對此的更好應用是:假設您只想從<h1> Chongchong </h1>中單獨獲得標籤<h1>和</h1>,則希望它的正則表達式為<.+>但實際上,它將捕獲整個文本(<h1> Hello Chongchong</h1>)並將其作為一個整體處理。 這時候用?就可以解決

加'?'在量詞前面有時被稱為懶惰模式。

簡而言之,貪婪模式表示匹配儘可能長的字符串,而懶惰模式表示匹配儘可能短的字符串。

字符類

字符類是代表一組字符的轉義序列。下面列出了Java中的一些預定義字符:

\d 表示任意數字;

\s表示空格字符(tab 空格等);

\w 任意單詞字符;

\D表示任意非數字;

\S 表示任意非空格字符;

\W表示任意非單詞字符。

Java中使用正則表達式

好,學習了基礎正則知識後,我們來轉入到Java。來學習在Java中正則表達式的使用。在Java世界Java中的字符串類帶有一個內置的布爾方法,該方法稱為matchs,該方法用來對字符串進行正則匹配。

public static void main(String[] args) {

String value = "12345";

System.out.println("The Result is: "+value.matches("\\d{5}"));

}

上面的代碼段將返回「結果為:true」,因為值(12345)恰好匹配5個字符。除5以外的任何其他值都將返回「結果為:false」。

Pattern/Matcher匹配

除了String類的matchs方法之外,java.util.regex包中也有正則表達式所需的類。它們由三類組成:

Pattern:這是正則表達式的編譯表示。要使用此功能,必須首先在模式類中調用靜態方法(編譯),該方法返回一個模式對象。

Matcher:這是解釋模式並針對輸入字符串執行匹配操作的引擎。要獲得一個對象,必須在Pattern對象上調用matcher方法。

PatternSyntaxException:這表示正則表達式模式中的錯誤

可以使用用模式Pattern/Matcher匹配字符串,一個例子是:

String value = "12345";

String regex = "\\d{5}";

Pattern pattern = Pattern.compile(regex);

Matcher matcher = pattern.matcher(value);

System.out.println("The Result is: "+matcher.matches());

獲取匹配的字符

Matcher支持find和方法lookingAt()獲取匹配的字符,一個例子:

Pattern p=Pattern.compile("\\d+");

Matcher m=p.matcher("aaa2223bb");

m.find();//2223

m.start();//3

m.end();//7,這是2223後的索引號

m.group();//2223

也可以使用lookingAt()方法,只之前的字符串:

Mathcer m2=m.matcher("2223bb");

m.lookingAt(); // 2223

m.start(); // 0,由於lookingAt()只能匹配前面的字符串, start()方法總是返回0

m.end(); // 4

m.group(); // 2223

性能問題

這樣需要每次都先創建 Pattern/Matcher對象耗費資源太大,性能不行。使用Pattern/Matcher是在String類中實現了方法匹配。因此,對於匹配的每個字符串,它都會在匹配之前創建一個Pattern對象。為了解決這個問題,我們可以使用預編譯方法,下面是一個實例:

上面的代碼將數組中的所有元素與特定的正則表達式([a-zA-Z]*log[a-zA-Z]*)進行匹配。正則表達式用來獲取所有帶有「log」一詞的文本。在與正則表達式匹配之前,必須先編譯該表達式(Pattern.compile);

第一個方法matchUsingPatternMatcher()在尋找匹配項之前先編譯模式,而第二個方法matchUsingStringMatches()創建一個新的模式對象

數組中每個元素的鏡像(Pattern.compile())操作比較耗費內存,並且當數據/文本過多時,還可能會導致內存洩漏

因此,如果在處理大量數據比較關心性能時,請使用Pattern/Matcher類先進行編譯,然後使用實例來匹配文本。

相關焦點

  • Java 正則表達式教程及示例
    本教程旨在幫助你駕馭Java正則表達式,同時也幫助我複習正則表達式。什麼是正則表達式?正則表達式定義了字符串的模式。正則表達式可以用來搜索、編輯或處理文本。正則表達式並不僅限於某一種語言,但是在每種語言中有細微的差別。Java正則表達式和Perl的是最為相似的。
  • Java的正則表達式和捕獲組
    正則表達式定義了字符串的模式。正則表達式可以用來搜索、編輯或處理文本。正則表達式並不僅限於某一種語言,在Java、JavaScript等語言都存在,但是在每種語言中有細微的差別。Java正則表達式正則表達式實例一個字符串其實就是一個簡單的正則表達式,例如 Hello World正則表達式匹配 "Hello World" 字符串。.
  • C++、Java、JavaScript中的正則表達式
    上面一個示例中用到的「^」、「w」、「{5,17}」等都是正則表達式中的常用符號,這些符號在正則表達式中都有特殊的含意。下面這個表格是Java中的正則表達式常用符號的含意(只抽取了其常用的部分進行說明,就這些部分其實可以解決關於正則表達式的絕大多數的問題了)。
  • java正則表達式入坑指南
    在日常開發工作中,無論你使用的語言是java、python、shell、golang還是C#, 正則表達式是程式語言中幾乎繞不開的話題。有了它,可以幫你快速定位到符合條件的文本內容。今天小編帶大家一起來學習下正則表達式,相信通過這篇文章的介紹,能為以後的工作提供一個更清晰的思路。
  • JavaScript正則表達式「程式設計師培養之路第十二天」
    只不過是一個特殊的字符串主要實現對字符串的匹配、分割、查找、替換等操作 正則表達式的主要作用: 正則匹配: 可以測試字符串內容是否可以與正則相匹配 替換文本: 根據模式匹配字符串中的特定內容,進行替換、刪除 提取數據: 根據模式匹配從字符串中提取內容,生成數組
  • 乾貨:java正則表達式匯總
    Email 正則表達式模式  ^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.IP位址正則表達式模式  ^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.  ([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?
  • Java和Groovy正則使用
    對於第一種返回json數據的可以直接用jsonobject解析。而第二種往往用HTML解析類做起來比較麻煩,特別是提取表單信息的時候,所以我直接當做string信息,通過正則表達式提取想要的信息。;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.util.ArrayList;import java.util.List;import java.util.regex.Matcher;import java.util.regex.Pattern;
  • 正則表達式在VBA中間是如何應用?正則表達式的實現方式?
    Hi,大家好,本章節開始將會從零開始和大家用圖文的方式,讓你從零基礎學會正則表達式!有興趣的小夥伴可以持續關注我,或者在專欄中進行查看自我學習,願與君攜手前行!在上一個章節說到正則表達式的入門級知識點,本節將會與大家分享一下正則表達式的是具體實現方式是怎麼樣的?
  • 8分鐘看完,徹底掌握Java正則表達式的十大問題!
    這篇文章總結了有關Java正則表達式的主要問題。希望可以給同學們帶來java學習路上的成長!1.如何從字符串中提取數字?使用正則表達式的一個常見問題是將所有數字提取到整數數組中。4.如何轉義文本以進行正則表達式?通常,正則表達式使用「 \」轉義結構,但是要在反斜槓之前加上另一個反斜槓以使Java字符串得以編譯是很痛苦的。用戶還有另一種方式將字符串Literals傳遞給Pattern,例如「 $ 5」。
  • 正則表達式入門教程 + 免費在線正則測試工具推薦
    正則表達式在計算機領域幾乎無所不在,但它又很難掌握,新手容易犯暈。如果你還處於入門學習階段,單靠腦子憑空寫一些複雜的正則,很難保證準確性,後面往往要花費大量時間去調試。其實,藉助一些可視化的正則測試工具網站,不僅能節省大量時間,還能對正則有更深的理解……什麼是正則表達式?
  • 認識正則表達式(Java語言基礎)
    正則表達式:字符串表示正確規則的式子首先新建一個工程,創建一個類我們在獲取當前系統時間的時候,我們可以按照下面的方式輸出。會發現輸出的時間並不是很容易閱讀,我們能不能修改下它的顯示?首先我們需要了解一個方法matches(),該方法用於檢測字符串是否匹配給定的正則表達式,在字符串匹配給定的正則表達式時,返回 true,否則false。
  • 程式設計師入門基礎:python的正則表達式
    正則表達式是一個特殊的字符序列,它能幫助我們方便的檢查一個字符串是否與某種模式匹配。Python提供Perl 風格的正則表達式模式。re 模塊使 Python 語言擁有全部的正則表達式功能。一、正則表達式1、字符元素(可跳過)字符的匹配元素,比較瑣碎,簡單了解後即可,後期邊用邊查就記住了。
  • 刨根究底正則表達式(1):開篇
    正則表達式目前市面上並不缺乏專業著作,比如那本被譽為正則表達式學習聖經的《精通正則表達式》就很值得一讀,另外該書的譯者餘晟先生所寫的《正則指引》也不錯。如果僅用於入門,則《正則表達式必知必會》肯定不能錯過,還有網上流傳極廣的《正則表達式30分鐘入門教程》也是不錯的入門資料。但是,結合我自身痛苦的正則表達式學習經歷和運用體會,僅有這些是遠遠不夠的。
  • Python正則表達式的7個使用典範
    但是,Python中的正則表達式在實際使用過程中還是有一些細小的差別。將介紹Python中對字符串進行搜索和查找的一些方法,討論如何使用分組來處理我們查找到的匹配對象的子項。使用的Python中正則表達式的模塊通常叫做『re'。
  • JMeter關聯:JMeter正則表達式提取器與JSON提取器
    這就要用到【正則表達式提取器】了。在HTTP請求getRegionDataset上添加【後置處理器】-【正則表達式提取器】。2、【正則表達式提取器】:正則表達式是相對繁瑣抽象的,理解和記憶難度較高,因此這裡對JMeter中能用到的正則表達式語法(主要是限定符)進行一下講解。據我個人經驗,(.+?)這個表達式基本就夠用了,何況正則表達式提取遠不如JSON提取器使用頻率高,所以這一節大可以略過,直接看第三節。
  • Java正則表達式基礎知識--5個學習步驟
    了解正則表達式概念及基本構造元素(本文目標);2. 通過練習能夠編寫出準確的可讀性較好的正則表達式,熟悉常用正則表達式;3. 理解正則引擎的內部機制及實現,能夠分析正則表達式的效率;4. 能夠編寫效率更高的正則表達式(以準確性和可讀性為前提);5. 能夠運用正則表達式去處理複雜的文本處理問題。1.
  • 正則表達式必須掌握的三個知識點,你知道多少?
    正則表達式又稱為規則表達式(模式表達式),它自身有完整的語法,為我們提供了一種更加靈活的字符串處理方法,正則表達式功能遠比php字符串函數強大的多。正則表達式通過特定的模式,與輸入的字符串比較,實現字符串的匹配、查找、替換等操作。這些模式的字符串,放在特定的正則表達式函數中使用才有效果。比如說「/\w+([-+.]
  • 正則表達式
    在我看來,正則表達式的主要用途有兩種:①查找特定的信息②查找並編輯特定的信息,也就是我們經常用的替換。。比如我們要在Word,記事本等裡面使用快捷鍵Ctrl+F,進行查找一個特定的字符,或者替換一個字符,這就使用了正則表達式。         正則表達式的功能非常強大,尤其是在文本數據進行處理中顯得更加突出。
  • python正則表達式
    2''' 3正則表達式, 簡稱為 regex, 是文本模式的描述方法。 4''' 5#7.2.1創建正則表達式對象 6''' 7python中所有正則表達式的函數都在re模塊中,向 re.compile()傳入一個字符串值, 8表示正則表達式,它將返回一個 Regex 模式對象(或者就簡稱為 Regex 對象)。
  • 正則表達式斷言精講Java語法實現
    斷言本文目的是講解正則表達式之斷言用法。目前網際網路上有很多博文對斷言講解的並不透徹,如果您剛開始學習斷言,相信此博文會對您有幫助。1.2.3.1 情景導入假設,我要獲得一個字符串裡面所有以空格開頭的英文詞語。