關鍵詞 正則
狀態機
環視匹配
等價轉換
限定符
內聯模式
java
不一樣類型的正則引擎對一樣的正則表達式執行的結果是不一樣的。搞清楚引擎是必要的。git
DFA(Deterministic Finite Automaton)爲肯定性有限自動機,NFA(Non-deterministic Finite Automaton)爲非肯定性有限自動機。正則表達式
能夠用以下的正則表達式測試當前編程語言採用的引擎是否 NFA:nfa|nfa not算法
js:"nfa,nfa not".match(/nfa|nfa not/) 結果 ["nfa", index: 0, input: "nfa,nfa not", groups: undefined]
js:/nfa|nfa not/.test('nfa') 結果 true
複製代碼
用上面的正則表達式來測試字符串 nfa not,NFA 引擎在檢測知足 nfa 就返回匹配成功的結果了,而 DFA 則會嘗試繼續查找,也就是說會獲得「最長的匹配結果」。編程
知識點:自動機、自動機bash
如/\d\w+/這個正則生成的狀態機圖:網絡
關於正則引擎如何工做這裏有一個不錯的說明,先說明了DFA工做的方法,而後又引出了「回溯」less
DFA類型 | 語言 |
---|---|
DFA | awk (大多數版本)、egrep(大多數版本)、flex、lex、MySQL、Procmail |
傳統型NFA | GNU Emacs、Java、grep(大多數版本)、less、more、.NET語言、PCRE library、Perl、PHP(全部三套正則庫)、Python、Ruby、sed(大多數版本)、vi ,JavaScript |
POSIX NFA | mawk、Mortice Kern Systems’ utilities、GNU Emacs (明確指定時使用) |
DFA/NFA | 混合 GNU awk、GNU grep/egrep、Tcl |
不一樣的語言對於正則表達式符號的支持狀況也是不一樣的。 編程語言
簡潔版post
?
表示匹配0個或1個+
表示匹配1-無窮*
表示匹配0-無窮.
表示除\n以外的任意字符^
爲匹配輸入字符串的開始位置$
匹配結束位置space character
的首字母。wsb 和 WSB 是相反的
等價
\w = [A-Za-z0-9_]
, 展開看好理解分解: 沒法一步就完成的需求能夠分解,如獲取網頁中的圖片地址, 先獲取img標籤,而後再從標籤中獲取src值
參考版
特別字符 | 描述 |
---|---|
$ | 匹配輸入字符串的結尾位置。若是設置了 RegExp 對象的 Multiline 屬性,則$ 也匹配 '\\n' 或 '\\r'。要匹配 $ 字符自己,請使用 \\$ 。 |
( ) | 標記一個子表達式的開始和結束位置。子表達式能夠獲取供之後使用。要匹配這些字符,請使用 \( 和 \)。 |
* | 匹配前面的子表達式零次或屢次。要匹配 * 字符,請使用 \*。 |
+ | 匹配前面的子表達式一次或屢次。要匹配 + 字符,請使用 \+。 |
. | 匹配除換行符 \n 以外的任何單字符。要匹配 . ,請使用 \. 。 |
[ | 標記一箇中括號表達式的開始。要匹配 [,請使用 \[。 |
? | 匹配前面的子表達式零次或一次,或指明一個非貪婪限定符。要匹配 ? 字符,請使用 \?。 |
\ | 將下一個字符標記爲或特殊字符、或原義字符、或向後引用、或八進制轉義符。例如, 'n' 匹配字符 'n'。'\n' 匹配換行符。序列 '\\' 匹配 "\",而 '\(' 則匹配 "("。 |
^ | 匹配輸入字符串的開始位置,除非在方括號表達式中使用,此時它表示不接受該字符集合。要匹配 ^ 字符自己,請使用 \^。 |
{ | 標記限定符表達式的開始。要匹配 {,請使用 \{。 |
| | 指明兩項之間的一個選擇。要匹配 |,請使用 \|。 |
限定符用來指定正則表達式的一個給定組件必需要出現多少次才能知足匹配。有 * 或 + 或 ? 或 {n} 或 {n,} 或 {n,m} 共6種。
正則表達式能夠包含子表達式、小括號(子表達式部分)、中括號(主幹部分)、大括號(限定部分)。這些括號組合是比較靈活的,能夠相互包含(但大括號能不能包含其餘括號)。
源字符串:<div>a test</div>
正則表達式:(?<=<div>)[^<]+(?=</div>)
複製代碼
Lookaround, 也叫零寬斷言
示例1:
金額匹配: `(^0\.[0-9]{1,2}$)|(^[1-9]\d+\.[0-9]{1,2}$)|(^[1-9]\d+$)`
金額匹配(環視匹配): `(?!^0\d+|\D*0$)^[0-9]{1,7}(\.[0-9]{1,2})?$`
複製代碼
這裏常規金額匹配由三個子表達式組成,要排除整數部分爲0開頭的狀況,整個過程比較冗長。換成環視匹配後就簡單多了,環視匹配表達式的含義爲 匹配除0開頭的整數部分和非數字,整數部分長度1-7位。
優化金額 前:/^\d+(\.\d{1,2})?$/
問題:12.校驗經過; 優化後:/^\d+[.]\d{1,2}$|^\d+$/
有「.」 小數部分必填。
示例2:
源字符串:aa<p>one</p>bb<div>two</div>cc
正則表達式:<(?!/?p\b)[^>]+>
複製代碼
這個正則的意義就是匹配除了<p···>或
以外的全部標籤 按圖所示,這個正則中<就匹配它自己,(?!/?p\b)是一個順序否認表達式,子表達式是</?p\b,意思是這個表達式的右邊不能是字符【/p】或者【p】,問號是表明匹配一次或者不匹配,你們應該還記得。而後[^>]+中的[^···]是排除型字符組,表示的是除【>】之外的字符均可以匹配,匹配的數量是最少一次,最多不限制。最後一個表達式>的意義是匹配它自己。 上面整個表達式的含義就是:匹配【<(<右邊不能是p或/p)(除>的字符N個)>】這樣一個文本。由此例子,咱們也能夠看出,表達式一般能夠拆分紅一個個的子表達式,最後把它們連起來造成一個完整的表達式。(?=Expression)
順序確定環視,表示所在位置右側可以匹配Expression
(?!Expression)
順序否認環視,表示所在位置右側不能匹配Expression
複製代碼
(?<=Expression)
逆序確定環視,表示所在位置左側可以匹配Expression
(?<!Expression)
逆序否認環視,表示所在位置左側不能匹配Expression
複製代碼
開頭都是 "?"
都包含 「=」或「!」; 確定否認。(都包含確定」=」或 否認「!」)
逆序包含"<"
內聯匹配模式特徵:正則前面的(?i)(?s)(?m)(?is)(?im)
稱爲內聯匹配模式,一般用內聯匹配模式代替使用枚舉值RegexOptions指定的全局匹配模式,寫起來更簡潔。
- 金額校驗包含最小最大值 ` ^0(?!\d+$)\.[0-9]?[1-9]{1}$|^2[0]{5}$|(?!^[0,2-9]\d+|\D*0$)^[0-9]{1,6}(\.[0-9]{1,2})?$`
- 手機號` ^1[3|5|8|6|9]\d{9}$ `
- 身份證` err:\d{15}$|\d{17}[\d{1}|X|x]$; right:^\d{17}[\d|X|x]{1}$|^\d{15}$`
- 通常信息填寫:` ^([^\x00-\xff]|[A-Za-z0-9_-]|[()()]|[\\s])*$ `; //assic0-255除數字、大小寫字母、之外的字符、這個正則殺馬特字符是能夠輸入的
- 中文\英文\數字\下劃線 `^([\u4e00-\u9fa5]|[A-Za-z0-9_-])*$`
- 各類電話號碼匹配,容許格式: 1398888888八、010-8888888八、010-88888888-88(轉接號)、400888888:`(^1[3|4|5|8|6|9]\d{9}$)|(^\d{3,4}-\d{7,8}(-\d{1,3})?$)|(^400\d{6}$)`
- 日期 `^[1,2]+[0-9]{3}-(0[1-9]|1[0,1,2])-(0[1-9]|([1,2][0-9]{1})|3[0,1]{1})$`
- 大於0的數 `/^[0-9]\d*(\.\d+)$/` => `/^[0-9]\d*(\.\d+)$/.test('1.0')`
1.驗證用戶名和密碼:("^[a-zA-Z]\w{5,15}$")正確格式:"[A-Z][a-z]_[0-9]"組成,而且第一個字必須爲字母6~16位;
2.驗證電話號碼:("^(\d{3,4}-)\d{7,8}$")正確格式:xxx/xxxx-xxxxxxx/xxxxxxxx;
3.驗證身份證號(15位或18位數字):("^\d{15}|\d{18}$");
4.驗證Email地址:("^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$");
5.只能輸入由數字和26個英文字母組成的字符串:("^[A-Za-z0-9]+$") ;
6.整數或者小數:^[0-9]+\.{0,1}[0-9]{0,2}$
7.只能輸入數字:"^[0-9]*$"。
8.只能輸入n位的數字:"^\d{n}$"。
9.只能輸入至少n位的數字:"^\d{n,}$"。
10.只能輸入m~n位的數字:。"^\d{m,n}$"
11.只能輸入零和非零開頭的數字:"^(0|[1-9][0-9]*)$"。
12.只能輸入有兩位小數的正實數:"^[0-9]+(.[0-9]{2})?$"。 => "^[0-9]+(\.[0-9]{2})?$"
13.只能輸入有1~3位小數的正實數:"^[0-9]+(.[0-9]{1,3})?$"。=> "^[0-9]+(\.[0-9]{1,3})?$"。
14.只能輸入非零的正整數:"^\+?[1-9][0-9]*$"。
15.只能輸入非零的負整數:"^\-[1-9][]0-9"*$。
16.只能輸入長度爲3的字符:"^.{3}$"。
17.只能輸入由26個英文字母組成的字符串:"^[A-Za-z]+$"。
18.只能輸入由26個大寫英文字母組成的字符串:"^[A-Z]+$"。
19.只能輸入由26個小寫英文字母組成的字符串:"^[a-z]+$"。
20.驗證是否含有^%&',;=?$\"等字符:"[^%&',;=?$\x22]+"。 21.只能輸入漢字:"^[\u4e00-\u9fa5]{0,}$" 22.驗證URL:"^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$"。 23.驗證一年的12個月:"^(0?[1-9]|1[0-2])$"正確格式爲:"01"~"09"和"1"~"12"。 24.驗證一個月的31天:"^((0?[1-9])|((1|2)[0-9])|30|31)$"正確格式爲;"01"~"09"和"1"~"31"。 25.獲取日期正則表達式:\d{4}[年|\-|\.]\d{\1-\12}[月|\-|\.]\d{\1-\31}日? 評註:可用來匹配大多數年月日信息。 26.匹配雙字節字符(包括漢字在內):[^\x00-\xff] 評註:能夠用來計算字符串的長度(一個雙字節字符長度計2,ASCII字符計1) 27.匹配空白行的正則表達式:\n\s*\r 評註:能夠用來刪除空白行 28.匹配HTML標記的正則表達式:<(\S*?)[^>]*>.*?</>|<.*? /> 網上流傳的版本太糟糕,上面這個也僅僅能匹配部分,對於複雜的嵌套標記依舊無能爲力 var regexp =/^([\u4e00-\u9fa5]|[A-Za-z0-9_-])*$/g; if(!regexp.test(content.trim())){ // 不符合正則 } - .*匹配除 \n 之外的任何字符。 - /[\u4E00-\u9FA5]/ 漢字 - /[\uFF00-\uFFFF]/ 全角符號 - /[\u0000-\u00FF]/ 半角符號 - Java不支持 ?、+、|、(),那應該怎麼實現呢? 首先要知道這件事,以後在java平臺寫正則時要看java的文檔 複製代碼
記住經常使用符號是必要的,長時間不用忘記也很正常,查詢手冊在這裏