Java正則表達式詳解

正則表達式的概念:

       正則表達式是一個字符串,使用單個字符串來描述、用來定義匹配規則,匹配一系列符合某個句法規則的字符串。在開發中,正則表達式通常被用來檢索、替換那些符合某個規則的文本。

基礎

元字符

代碼 說明
. 匹配除換行符以外的任意字符
\w 匹配字母或數字或下劃線或漢字
\s 匹配任意的空白符
\d 匹配數字
^ 匹配字符串的開始
$ 匹配字符串的結束
\b 匹配字符串的結束

重複

代碼/語法 說明
* 重複零次或更多次
+ 重複一次或更多次
? 重複零次或一次
{n} 重複n次
{n,} 重複n次或更多次
{n,m} 重複n到m次

字符類

想查找數字,字母或數字,空白是很簡單的,因爲已經有了對應這些字符集合的元字符,但是如果你想匹配沒有預定義元字符的字符集合(比如元音字母a,e,i,o,u),應該怎麼辦?
很簡單,你只需要在方括號裏列出它們就行了,像[aeiou]就匹配任何一個英文元音字母,[.?!]匹配標點符號(.或?或!)。
我們也可以輕鬆地指定一個字符範圍,像[0-9]代表的含意與\d就是完全一致的:一位數字;同理[a-z0-9A-Z_]也完全等同於\w(如果只考慮英文的話)。


分枝條件

用|把不同的規則分別表達。
如:0\d{2}-\d{8}|0\d{3}-\d{7}這個表達式能匹配兩種以連字號分隔的電話號碼:一種是三位區號,8位本地號(如010-12345678),一種是4位區號,7位本地號(0376-2233445)。

反義

代碼/語法 說明
\W 匹配任意不是字母,數字,下劃線,漢字的字符
\S 匹配任意不是空白符的字符
\D 匹配任意非數字的字符
\B 匹配不是單詞開頭或結束的位置
[^x] 匹配除了x以外的任意字符
[^aeiou] 匹配除了aeiou這幾個字母以外的任意字符


分組

重複單個字符直接在字符後面加上限定符就行了,但如果想要重複多個字符又該怎麼辦?你可以用小括號來指定子表達式(也叫做分組),然後你就可以指定這個子表達式的重複次數了,你也可以對子表達式進行其它一些操作。
使用小括號指定一個子表達式後,匹配這個子表達式的文本(也就是此分組捕獲的內容)可以在表達式或其它程序中作進一步的處理。捕獲組可以通過從左到右計算其開括號來編號。例如,在表達式 ((A)(B(C))) 中,存在四個這樣的組:

    ((A)(B(C)))
    (A)
    (B(C))
    (C)

組零始終代表整個表達式。

之所以這樣命名捕獲組是因爲在匹配中,保存了與這些組匹配的輸入序列的每個子序列。捕獲的子序列稍後可以通過 Back 引用在表達式中使用,也可以在匹配操作完成後從匹配器獲取。

與組關聯的捕獲輸入始終是與組最近匹配的子序列。如果由於量化的緣故再次計算了組,則在第二次計算失敗時將保留其以前捕獲的值(如果有的話)例如,將字符串 “aba” 與表達式 (a(b)?)+ 相匹配,會將第二組設置爲 “b”。在每個匹配的開頭,所有捕獲的輸入都會被丟棄。

以 (?) 開頭的組是純的非捕獲 組,它不捕獲文本,也不針對組合計進行計數。

後向引用用於重複搜索前面某個分組匹配的文本。例如:
\b(\w+)\b\s+\1\b可以用來匹配重複的單詞,像go go, 或者kitty kitty。

也可以自己指定子表達式的組名。要指定一個子表達式的組名,請使用這樣的語法:(?<Word>\w+)(或者把尖括號換成’也行:(?'Word'\w+)),這樣就把\w+的組名指定爲Word了。要反向引用這個分組捕獲的內容,你可以使用\k<Word>,所以上一個例子也可以寫成這樣:\b(?<Word>\w+)\b\s+\k<Word>\b
 

零寬斷言

(?=exp)也叫零寬度正預測先行斷言,它斷言被匹配的字符串以表達式exp結尾但除了結尾以外的部分。比如\b\w+(?=ing\b),匹配以ing結尾的單詞的前面部分(除了ing以外的部分),如查找I’m singing while you’re dancing.時,它會匹配sing和danc。 
(?<=exp)也叫零寬度正回顧後發斷言,它斷言自身出現的位置的前面能匹配表達式exp。比如(?<=\bre)\w+\b會匹配以re開頭的單詞的後半部分(除了re以外的部分),例如在查找reading a book時,它匹配ading。

代碼/語法 說明
(?=exp) 匹配exp前面的位置
(?<=exp) 匹配exp後面的位置
(?!exp) 匹配後面跟的不是exp的位置
(? 匹配前面不是exp的位置

註釋

小括號的另一種用途是通過語法(?#comment)來包含註釋。例如:2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d 
\d?(?#0-199)

貪婪與懶惰

語法 說明
*? 重複任意次,但儘可能少重複
+? 重複1次或更多次,但儘可能少重複
?? 重複0次或1次,但儘可能少重複
{n,m}? 重複n到m次,但儘可能少重複
{n,}? 重複n次以上,但儘可能少重複

當正則表達式中包含能接受重複的限定符時,通常的行爲是(在使整個表達式能得到匹配的前提下)匹配儘可 
能多的字符。考慮這個表達式:a.*b,它將會匹配最長的以a開始,以b結束的字符串。如果用它來搜索aabab的 
話,它會匹配整個字符串aabab。這被稱爲貪婪匹配。 
有時,我們更需要懶惰匹配,也就是匹配儘可能少的字符。前面給出的限定符都可以被轉化爲懶惰匹配模式, 
只要在它後面加上一個問號?。這樣.*?就意味着匹配任意數量的重複,但是在能使整個匹配成功的前提下使用 
最少的重複。現在看看懶惰版的例子吧: 
a.*?b匹配最短的,以a開始,以b結束的字符串。如果把它應用於aabab的話,它會匹配aab(第一到第三個字 
符)和ab(第四到第五個字符)。
 

POSIX 字符類(僅 US-ASCII)

語法 說明
\p{Lower} 小寫字母字符:[a-z]
\p{Upper} 大寫字母字符:[A-Z]
\p{ASCII} 所有 ASCII:[\x00-\x7F]
\p{Alpha} 字母字符:[\p{Lower}\p{Upper}]
\p{Digit} 十進制數字:[0-9]
\p{Alnum} 字母數字字符:[\p{Alpha}\p{Digit}]
\p{Punct} 標點符號:`!"#$%&'()*+,-./:;<=>?@[\]^_{|}~
\p{Graph} 可見字符:[\p{Alnum}\p{Punct}]
\p{Print} 可打印字符:[\p{Graph}\x20]
\p{Blank} 空格或製表符:[ \t]
\p{Cntrl} 控制字符:[\x00-\x1F\x7F]
\p{XDigit} 十六進制數字:[0-9a-fA-F]
\p{Space} 空白字符:[ \t\n\x0B\f\r]

引用

語法 說明
\ Nothing,但是引用以下字符
\Q Nothing,但是引用所有字符,直到 \E
\E Nothing,但是結束從 \Q 開始的引用

如:\Q\w+\E表示字符串\w+而不是正則中的單詞字符:[a-zA-Z_0-9]

其他

語法 說明
\xhh 十六進制值爲0xhh的字符
\uhhhh 十六進制表示爲0xhhhh的Unicode字符
\t 製表符Tab
\n 換行符
\r 回車
\f 換頁
\e 轉義(Escape)

處理選項

上面介紹了幾個選項如忽略大小寫,處理多行等,這些選項能用來改變處理正則表達式的方式。下面是Java中常用的正則表達式選項:

名稱 說明
CASE_INSENSITIVE 匹配時區分大小寫
MULTILINE 更改^$的含義,使它們分別在任意一行的行首和行尾匹配,而不僅僅在整個字符串的開頭和結尾匹配。(在此模式下,$的精確含意是:匹配\n之前的位置以及字符串結束前的位置.)
DOTALL 在 dotall 模式中,表達式 . 可以匹配任何字符,包括行結束符。默認情況下,此表達式不匹配行結束符。
UNICODE_CASE 指定此標誌後,由 CASE_INSENSITIVE 標誌啓用時,不區分大小寫的匹配將以符合 Unicode Standard 的方式完成。默認情況下,不區分大小寫的匹配假定僅匹配 US-ASCII 字符集中的字符。通過嵌入式標誌表達式 (?u) 也可以啓用 Unicode 感知的大小寫摺疊。指定此標誌可能對性能產生影響。
CANON_EQ 啓用規範等價。指定此標誌後,當且僅當其完整規範分解匹配時,兩個字符纔可視爲匹配。例如,當指定此標誌時,表達式 “a\u030A” 將與字符串 “\u00E5” 匹配。默認情況下,匹配不考慮採用規範等價。不存在可以啓用規範等價的嵌入式標誌字符。指定此標誌可能對性能產生影響。
UNIX_LINES 啓用 Unix 行模式。在此模式中,.、^ 和 $ 的行爲中僅識別 ‘\n’ 行結束符。通過嵌入式標誌表達式 (?d) 也可以啓用 Unix 行模式。
LITERAL 指定此標誌後,指定模式的輸入字符串就會作爲字面值字符序列來對待。輸入序列中的元字符或轉義序列不具有任何特殊意義。標誌 CASE_INSENSITIVE 和 UNICODE_CASE 在與此標誌一起使用時將對匹配產生影響。其他標誌都變得多餘了。不存在可以啓用字面值解析的嵌入式標誌字符。
UNICODE_CHARACTER_CLASS  
COMMENTS 模式中允許空白和註釋。此模式將忽略空白和在結束行之前以 # 開頭的嵌入式註釋。通過嵌入式標誌表達式 (?x) 也可以啓用註釋模式。

JAVA

基本用法

Pattern pattern = Pattern.compile("\\ba\\w*\\b");
Matcher matcher = pattern.matcher("abcdab cccabcd aaacd");
int index = 0;
while (matcher.find()) {
    String res = matcher.group();
    System.out.println(index + ":" + res);
    index++;
}

\\ba\\w*\\b表示匹配以字母a爲開頭的單詞。 
Pattern.compile(regex)表示將給定的正則表達式編譯到具有給定標誌的模式中。 
matcher(str)創建匹配給定輸入與此模式的匹配器。 
mather.find()嘗試查找與該模式匹配的輸入序列的下一個子序列。 
此方法從匹配器區域的開頭開始,如果該方法的前一次調用成功了並且從那時開始匹配器沒有被重置,則從以前匹配操作沒有匹配的第一個字符開始。 
如果匹配成功,則可以通過 start、end 和 group 方法獲取更多信息。 
group() 返回由以前匹配操作所匹配的輸入子序列。 
打印結果: 


不同

從上例中可以看出,Java中的正則表達式與之前所說不一致(多了一個\),在其他語言中\\表示我想在正則表達式中插入一個普通的反斜線,請不要給它任何特殊的意義,而在Java中,\\的意思是我想要插入一個正則表達式的反斜線,所以其後的字符具有特殊的意義。

如果想表示數字,則是\\d。如果要插入普通的反斜線,則是\\\\

String

String類中有幾種方法可以使用正則表達式:

方法 返回類型 功能 示例
matches() boolean 告知此字符串是否匹配給定的正則表達式。 "-1234".matches("^-?\\d+$") => true
replaceAll(String regex, String replacement) String 使用給定的 replacement 替換此字符串所有匹配給定的正則表達式的子字符串。 "a1b2c3".replaceAll("[a-zA-z]", "") => 123
replaceFirst(String regex, String replacement) String 使用給定的 replacement 替換此字符串匹配給定的正則表達式的第一個子字符串。 "Hello World! Hello Everyone!".replaceFirst("\\s", "") => HelloWorld! Hello Everyone!
split(String regex) String[] 根據給定正則表達式的匹配拆分此字符串。 "boo:and:foo".split(":") => { "boo", "and", "foo" }
split(String regex, int limit) String[] 根據給定正則表達式的匹配拆分此字符串。 "boo:and:foo".split(":", 5) => { "boo", "and", "foo" }

split(String regex, int limit)方法中limit 參數控制模式應用的次數,因此影響所得數組的長度。如果該限制 n 大於 0,則模式將被最多應用 n - 1 次,數組的長度將不會大於 n,而且數組的最後一項將包含所有超出最後匹配的定界符的輸入。如果 n 爲非正,那麼模式將被應用儘可能多的次數,而且數組可以是任何長度。如果 n 爲 0,那麼模式將被應用儘可能多的次數,數組可以是任何長度,並且結尾空字符串將被丟棄。

例如,字符串 "boo:and:foo" 使用這些參數可生成以下結果:
 

Regex Limit 結果
: 2 { "boo", "and:foo" }
: 5 { "boo", "and", "foo" }
: -2 { "boo", "and", "foo" }
o 5 { "b", "", ":and:f", "", "" }
o -2 { "b", "", ":and:f", "", "" }
o 0 { "b", "", ":and:f" }

調用此方法的 str.split(regex, n) 形式與以下表達式產生的結果完全相同:Pattern.compile(regex).split(str, n)

 

java.util.regex


在regex包中,包括了兩個類,Pattern(模式類)和Matcher(匹配器類)。Pattern類是用來表達和陳述所要搜索模式的對象,Matcher類是真正影響搜索的對象。另加一個新的例外類,PatternSyntaxException,當遇到不合法的搜索模式時,會拋出例外。

Pattern

簡介 
正則表達式的編譯表示形式。

指定爲字符串的正則表達式必須首先被編譯爲此類的實例。然後,可將得到的模式用於創建 Matcher 對象,依照正則表達式,該對象可以與任意字符序列匹配。執行匹配所涉及的所有狀態都駐留在匹配器中,所以多個匹配器可以共享同一模式。

因此,典型的調用順序是
 

 Pattern p = Pattern.compile("a*b");
 Matcher m = p.matcher("aaaaab");
 boolean b = m.matches();

在僅使用一次正則表達式時,可以方便地通過此類定義 matches 方法。此方法編譯表達式並在單個調用中將輸入序列與其匹配。語句

 boolean b = Pattern.matches("a*b", "aaaaab");

等效於上面的三個語句,儘管對於重複的匹配而言它效率不高,因爲它不允許重用已編譯的模式。 
此類的實例是不可變的,可供多個併發線程安全使用。Matcher 類的實例用於此目的則不安全。

常用方法

Pattern類中最重要的方法便是compilematcher,上面已經給出示例。下面看看其他方法:

方法 返回類型 功能 示例
flags() int 返回此模式的匹配標誌。 Pattern.compile("\\w*", Pattern.MULTILINE).flags() => 8
pattern() String 返回在其中編譯過此模式的正則表達式。 Pattern.compile("\\w*").pattern() => \w*
static quote(String s) String 返回指定 String 的字面值模式 String。 Pattern.quote("\\w+") => \Q\w+\E

Matcher

  • 簡介

通過解釋 Pattern 對 character sequence 執行匹配操作的引擎。

通過調用模式的 matcher 方法從模式創建匹配器。創建匹配器後,可以使用它執行三種不同的匹配操作:

  • matches 方法嘗試將整個輸入序列與該模式匹配。

  • lookingAt 嘗試將輸入序列從頭開始與該模式匹配。

  • find 方法掃描輸入序列以查找與該模式匹配的下一個子序列。

每個方法都返回一個表示成功或失敗的布爾值。通過查詢匹配器的狀態可以獲取關於成功匹配的更多信息。

匹配器在其輸入的子集(稱爲區域)中查找匹配項。默認情況下,此區域包含全部的匹配器輸入。可通過 region 方法修改區域,通過 regionStart 和 regionEnd 方法查詢區域。區域邊界與某些模式構造交互的方式是可以更改的。

此類還定義使用新字符串替換匹配子序列的方法,需要時,可以從匹配結果計算出新字符串的內容。可以先後使用 appendReplacement 和 appendTail 方法將結果收集到現有的字符串緩衝區,或者使用更加便捷的 replaceAll 方法創建一個可以在其中替換輸入序列中每個匹配子序列的字符串。

匹配器的顯式狀態包括最近成功匹配的開始和結束索引。它還包括模式中每個捕獲組捕獲的輸入子序列的開始和結束索引以及該子序列的總數。出於方便的考慮,還提供了以字符串的形式返回這些已捕獲子序列的方法。

匹配器的顯式狀態最初是未定義的;在成功匹配導致 IllegalStateException 拋出之前嘗試查詢其中的任何部分。每個匹配操作都將重新計算匹配器的顯式狀態。

匹配器的隱式狀態包括輸入字符序列和添加位置,添加位置最初是零,然後由 appendReplacement 方法更新。

可以通過調用匹配器的 reset() 方法來顯式重置匹配器,如果需要新輸入序列,則調用其 reset(CharSequence) 方法。重置匹配器將放棄其顯式狀態信息並將添加位置設置爲零。

此類的實例用於多個併發線程是不安全的。
 

  • 常用方法

matches() 

表示字符串完全符合給出的正則表達式所表示的範圍。只要有一個字符不匹配則返回false。如:

Pattern.matches("[a-z]", "aAbBcC")

返回false,因爲正則表達式表示的範圍不包含大寫字母。

find() 

find()嘗試查找與該模式匹配的輸入序列的下一個子序列。 
此方法從匹配器區域的開頭開始,如果該方法的前一次調用成功了並且從那時開始匹配器沒有被重置,則從以前匹配操作沒有匹配的第一個字符開始。 
如果匹配成功,則可以通過 start、end 和 group 方法獲取更多信息。

    Pattern pattern = Pattern.compile("[a-z]");
    Matcher matcher = pattern.matcher("aAbBcC");
    matcher.find();

返回true,因爲可以匹配到小寫字母。

需要注意的是在執行find()方法時,其內部指針會跟着變動,比如第一次調用完畢,此時的matcher.start()爲0,因爲第一個字母就匹配上了,而matcher.end()則返回2,因爲它返回的是最後不匹配(A)的位置的下一個索引,因此可以通過如下方法看到指針移動軌跡:
 

        Pattern p = Pattern.compile("\\d{3,5}");
        String s = "123-34345-234-00";
        while (m.find()) {
            System.out.println(m.start() + "-" + m.end());
        }

打印結果: 

可以看到,find方法比較實誠,善始善終,但我們有時候需要人工插手而不總是從頭到尾來一遍,這就涉及到find方法的另一個多態形式了。

find(int start) 
從指定位置開始匹配,使用此方法模擬find():

        int index = 0;
        while (m.find(index)) {
            System.out.println(m.start() + "-" + m.end());
            index = m.end();
        }

lookingAt() 
此方法總是從頭開始匹配,無論是否匹配上均立即返回相應結果,並且不再繼續匹配,語言乏力,此處使用find方法模擬:

    public static void main(String[] args) throws Exception {
        Pattern p = Pattern.compile("\\d{3,5}");
        String s = "123-34345-234-00";
        Matcher m = p.matcher(s);

        System.out.println(cosplayMethodLookingAt(m));
        System.out.println(cosplayMethodLookingAt(m));
        System.out.println(cosplayMethodLookingAt(m));
        System.out.println(cosplayMethodLookingAt(m));
    }

    private static boolean cosplayMethodLookingAt(Matcher m) {
        boolean res = m.find() && m.start() == 0;
        m.reset();
        return res;
    }

顯示效果與lookingAt方法相同,但內部實現不一樣:

    public static void main(String[] args) throws Exception {
        Pattern p = Pattern.compile("\\d{3,5}");
        String s = "123-34345-234-00";
        Matcher m = p.matcher(s);

        m.find();
        m.lookingAt();
        m.find();
        // 4
        System.out.println(m.start());
        cosplayMethodLookingAt(m);
        m.find();
        System.out.println(m.start());
    }

    private static boolean cosplayMethodLookingAt(Matcher m) {
        boolean res = m.find() && m.start() == 0;
        m.reset();
        return res;
    }

打印結果: 

由此可見,lookingAt方法並不會重置匹配使用的內部指針。

appendReplacement 
public Matcher appendReplacement(StringBuffer sb, String replacement)

實現非終端添加和替換步驟。 
此方法執行以下操作:

它從添加位置開始在輸入序列讀取字符,並將其添加到給定字符串緩衝區。在讀取以前匹配之前的最後字符(即位於索引 start() - 1 處的字符)之後,它就會停止。

它將給定替換字符串添加到字符串緩衝區。

它將此匹配器的添加位置設置爲最後匹配位置的索引加 1,即 end()。

替換字符串可能包含到以前匹配期間所捕獲的子序列的引用:g每次出現時,都將被group(g)的計算結果替換。g每次出現時,都將被group(g)的計算結果替換。 之後的第一個數始終被視爲組引用的一部分。如果後續的數可以形成合法組引用,則將被合併到 g 中。只有數字 ‘0’ 到 ‘9’ 被視爲組引用的可能組件。例如,如果第二個組匹配字符串 “foo”,則傳遞替換字符串 “2bar"將導致"foobar"被添加到字符串緩衝區。可能將美元符號(2bar"將導致"foobar"被添加到字符串緩衝區。可能將美元符號() 作爲替換字符串中的字面值(通過前面使用一個反斜線 ($))包括進來。

注意,在替換字符串中使用反斜線 () 和美元符號 ($) 可能導致與作爲字面值替換字符串時所產生的結果不同。美元符號可視爲到如上所述已捕獲子序列的引用,反斜線可用於轉義替換字符串中的字面值字符。

此方法設計用於循環以及 appendTail 和 find 方法中。例如,以下代碼將 one dog two dogs in the yard 寫入標準輸出流中:
 

 Pattern p = Pattern.compile("cat");
 Matcher m = p.matcher("one cat two cats in the yard");
 StringBuffer sb = new StringBuffer();
 while (m.find()) {
     m.appendReplacement(sb, "dog");
 }
 m.appendTail(sb);
 System.out.println(sb.toString());

輸出結果: 

appendTail

StringBuffer appendTail(StringBuffer sb) 

此方法從添加位置開始從輸入序列讀取字符,並將其添加到給定字符串緩衝區。可以在一次或多次調用 appendReplacement 方法後調用它來複制剩餘的輸入序列。

以上例來說,當匹配到第二個cat時,while語句塊中的代碼就失效了,此時後面的字符串s in the yard就需要使用appendTail方法來補齊,否則輸出結果就是:顯然有所缺失。

group

String group() 

返回由以前匹配操作所匹配的輸入子序列。 
對於具有輸入序列 s 的匹配器 m,表達式 m.group() 和 s.substring(m.start(), m.end()) 是等效的。 
注意,某些模式(例如,a*)匹配空字符串。當模式成功匹配輸入中的空字符串時,此方法將返回空字符串。

group(int group)

String group(int group) 

返回在以前匹配操作期間由給定組捕獲的輸入子序列。 
對於匹配器 m、輸入序列 s 和組索引 g,表達式 m.group(g) 和 s.substring(m.start(g), m.end(g)) 是等效的。

捕獲組是從 1 開始從左到右的索引。組零表示整個模式,因此表達式 m.group(0) 等效於 m.group()。

如果該匹配成功了,但指定組未能匹配輸入序列的任何部分,則返回 null。注意,某些組(例如,(a*))匹配空字符串。當這些的組成功匹配輸入中的空字符串時,此方法將返回空字符串。
 

        Pattern p = Pattern.compile("\\b\\w+(o\\w+)\\b");
        Matcher m = p.matcher("i love you");
        while (m.find()) {
            System.out.println("整個匹配結果=>"+m.group());
            System.out.println("一組匹配結果=>"+m.group(1));
        }

輸出結果:

其他

 

其他方法要麼可以融會貫通,比如start(int),要麼就是不常用,比如hasAnchoringBounds(),因此在需要的時候可以查看中文文檔。 
奉上連接:Matcher API 

 

常用正則

校驗數字的表達式

數字:^[0-9]*$ 
n位的數字:^\d{n}$ 
至少n位的數字:^\d{n,}$ 
m-n位的數字:^\d{m,n}$ 
零和非零開頭的數字:^(0|[1-9][0-9]*)$ 
非零開頭的最多帶兩位小數的數字:^([1-9][0-9]*)+(.[0-9]{1,2})?$ 
帶1-2位小數的正數或負數:^(\-)?\d+(\.\d{1,2})?$ 
正數、負數、和小數:^(\-|\+)?\d+(\.\d+)?$ 
有兩位小數的正實數:^[0-9]+(.[0-9]{2})?$ 
有1~3位小數的正實數:^[0-9]+(.[0-9]{1,3})?$ 
非零的正整數:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$ 
非零的負整數:^\-[1-9][]0-9″*$ 或 ^-[1-9]\d*$ 
非負整數:^\d+$ 或 ^[1-9]\d*|0$ 
非正整數:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$ 
非負浮點數:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$ 
非正浮點數:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$ 
正浮點數:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$ 
負浮點數:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$ 
浮點數:^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
 

校驗字符的表達式

漢字:^[\u4e00-\u9fa5]{0,}$ 
英文和數字:^[A-Za-z0-9]+$^[A-Za-z0-9]{4,40}$ 
長度爲3-20的所有字符:^.{3,20}$ 
由26個英文字母組成的字符串:^[A-Za-z]+$ 
由26個大寫英文字母組成的字符串:^[A-Z]+$ 
由26個小寫英文字母組成的字符串:^[a-z]+$ 
由數字和26個英文字母組成的字符串:^[A-Za-z0-9]+$ 
由數字、26個英文字母或者下劃線組成的字符串:^\w+$ 或 ^\w{3,20}$ 
中文、英文、數字包括下劃線:^[\u4E00-\u9FA5A-Za-z0-9_]+$ 
中文、英文、數字但不包括下劃線等符號:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$ 
可以輸入含有^%&',;=?$\”等字符:[^%&',;=?$\x22]+ 
禁止輸入含有~的字符:[^~\x22]+
 

特殊需求表達式

Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$ 
域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.? 
InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$ 
手機號碼:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$ 
電話號碼(“XXX-XXXXXXX”、”XXXX-XXXXXXXX”、”XXX-XXXXXXX”、”XXX-XXXXXXXX”、”XXXXXXX”和”XXXXXXXX):^($$\d{3,4}-)|\d{3.4}-)?\d{7,8}$ 
國內電話號碼(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7} 
身份證號(15位、18位數字):^\d{15}|\d{18}$ 
短身份證號碼(數字、字母x結尾):^([0-9]){7,18}(x|X)?$ 或 ^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$ 
帳號是否合法(字母開頭,允許5-16字節,允許字母數字下劃線):^[a-zA-Z][a-zA-Z0-9_]{4,15}$ 
密碼(以字母開頭,長度在6~18之間,只能包含字母、數字和下劃線):^[a-zA-Z]\w{5,17}$ 
強密碼(必須包含大小寫字母和數字的組合,不能使用特殊字符,長度在8-10之間):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$ 
日期格式:^\d{4}-\d{1,2}-\d{1,2} 
一年的12個月(01~09和1~12):^(0?[1-9]|1[0-2])$ 
一個月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$

xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$ 
中文字符的正則表達式:[\u4e00-\u9fa5] 
雙字節字符:[^\x00-\xff] (包括漢字在內,可以用來計算字符串的長度(一個雙字節字符長度計2,ASCII字符計1)) 
空白行的正則表達式:\n\s*\r (可以用來刪除空白行) 
HTML標記的正則表達式:<(\S*?)[^>]*>.*?</\1>|<.*? /> (網上流傳的版本太糟糕,上面這個也僅僅能部分,對於複雜的嵌套標記依舊無能爲力) 
首尾空白字符的正則表達式:^\s*|\s*$(^\s*)|(\s*$) (可以用來刪除行首行尾的空白字符(包括空格、製表符、換頁符等等),非常有用的表達式) 
騰訊QQ號:[1-9][0-9]{4,} (騰訊QQ號從10000開始) 
中國郵政編碼:[1-9]\d{5}(?!\d) (中國郵政編碼爲6位數字) 
IP地址:\d+\.\d+\.\d+\.\d+ (提取IP地址時有用) 
IP地址:((25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}\2
 

錢的輸入格式

有四種錢的表示形式我們可以接受:”10000.00″ 和 “10,000.00″, 和沒有 “分” 的 “10000″ 和 “10,000″:^[1-9][0-9]*$ 
這表示任意一個不以0開頭的數字,但是,這也意味着一個字符”0″不通過,所以我們採用下面的形式:^(0|[1-9][0-9]*)$ 
一個0或者一個不以0開頭的數字.我們還可以允許開頭有一個負號:^(0|-?[1-9][0-9]*)$ 
這表示一個0或者一個可能爲負的開頭不爲0的數字.讓用戶以0開頭好了.把負號的也去掉,因爲錢總不能是負的吧.下面我們要加的是說明可能的小數部分:^[0-9]+(.[0-9]+)?$ 
必須說明的是,小數點後面至少應該有1位數,所以”10.”是不通過的,但是 “10″ 和 “10.2″ 是通過的:^[0-9]+(.[0-9]{2})?$ 
這樣我們規定小數點後面必須有兩位,如果你認爲太苛刻了,可以這樣:^[0-9]+(.[0-9]{1,2})?$ 
這樣就允許用戶只寫一位小數。下面我們該考慮數字中的逗號了,我們可以這樣:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$ 
1到3個數字,後面跟着任意個 逗號+3個數字,逗號成爲可選,而不是必須:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$ 
備註:這就是最終結果了,別忘了”+”可以用”*”替代。如果你覺得空字符串也可以接受的話(奇怪,爲什麼?)最後,別忘了在用函數時去掉去掉那個反斜槓,一般的錯誤都在這裏

————————————————
原文鏈接:https://blog.csdn.net/Young4Dream/article/details/78868551

 

補充:之前工作中,密碼強度校驗

校驗規則: 密碼必須是 大小字母、小寫字母、特殊字符、數字這 4 種種的至少三種組合。

java正則表達式

^(?:(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])|(?=.*[A-Z])(?=.*[a-z])(?=.*[^A-Za-z0-9])|(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9])|(?=.*[a-z])(?=.*[0-9])(?=.*[^A-Za-z0-9])).+
public boolean isRightPass(String password){
		 //新密碼不符合系統要求:必須是數字、大寫字母、小寫字母、符號這4種中的至少3種組合!
    	 String regex ="^(?:(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])|(?=.*[A-Z])(?=.*[a-z])(?=.*[^A-Za-z0-9])|(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9])|(?=.*[a-z])(?=.*[0-9])(?=.*[^A-Za-z0-9])).+";
    	 Pattern pa =Pattern.compile(regex);
		 Matcher m = pa.matcher(password);
		 boolean b = m.find();
		 return b;
     }

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章