本文整理C#正則表達式的元字符,正則表達式是由字符構成的表達式,每一個字符表明一個規則,表達式中的字符分爲兩種類型:普通字符和元字符。普通字符是指字面含義不變的字符,按照徹底匹配的方式匹配文本,而元字符具備特殊的含義,表明一類字符。html
把文本看做是字符流,每一個字符放在一個位置上,例如,正則表達式 「Room\d\d\d」,前面四個字符Room是普通字符,後面的字符\是轉義字符,和後面的字符d組成一個元字符\d,表示該位置上有任意一個數字。正則表達式
用正則表達式的語言來描述是:正則表達式 「Room\d\d\d」共捕獲7個字符,表示「以Room開頭、以三個數字結尾」的一類字符串,咱們把這一類字符串稱做一個模式(Pattern),也稱做是一個正則。express
轉義字符是\,把普通字符轉義爲具備特殊含義的元字符,經常使用的轉義字符有:ui
在進行正則匹配時,把輸入文本看做是有順序的字符流,字符類元字符匹配的對象是字符,並會捕獲字符。所謂捕獲字符是指,一個元字符捕獲的字符,不會被其餘元字符匹配,後續的元字符只能從剩下的文本中從新匹配。spa
經常使用的字符類元字符:code
注意,轉義字符也屬於字符類元字符,在進行正則匹配時,也會捕獲字符。orm
定位符匹配(或捕獲)的對象是位置,它根據字符的位置來判斷模式匹配是否成功,定位符不會捕獲字符,是零寬的(寬度爲0),經常使用的定位符有:htm
量詞是指限定前面的一個正則出現的次數,量詞分爲兩種模式:貪婪模式和懶惰模式,貪婪模式是指匹配儘量多的字符,而懶惰模式是指匹配儘量少的字符。默認狀況下,量詞處於貪婪模式,在量詞的後面加上?來啓用懶惰模式。對象
注意,出現屢次是指前面的元字符出現屢次,例如,\d{2} 等價於 \d\d,只是出現兩個數字,並不要求兩個數字是相同的。要表示相同的兩個數字,必須使用分組來實現。blog
() 括號不只肯定表達式的範圍,還建立分組,()內的表達式就是一個分組,引用分組表示兩個分組匹配的文本是徹底相同的。定義一個分組的基本語法:
(pattern)
該類型的分組會捕獲字符,所謂捕獲字符是指:一個元字符捕獲的字符,不會被其餘元字符匹配,後續的元字符只能從剩下的文本中從新匹配。
1,分組編號和命名
默認狀況下,每一個分組自動分配一個組號,規則是:從左向右,按分組左括號的出現順序進行編號,第一個分組的組號爲1,第二個爲2,以此類推。也能夠爲分組指定名稱,該分組稱做命名分組,命名分組也會被自動編號,編號從1開始,逐個加1,爲分組指定名稱的語法是:
(?<
name>
pattern)
一般來講,分組分爲命名分組和編號分組,引用分組的方式有:
注意,分組只能後向引用,也就是說,從正則表達式文本的左邊開始,分組必須先定義,而後才能在定義以後面引用。
在正則表達式裏引用分組的語法爲「\number」,好比「\1」表明與分組1 匹配的子串,「\2」表明與分組2 匹配的字串,以此類推。
例如,對於 "<(.*?)>.*?</\1>" 能夠匹配 <h2>valid</h2>,在引用分組時,分組對應的文本是徹底相同的。
2,分組構造器
分組構造方法以下:
(?<
name >
pattern):把匹配的子表達式捕獲到命名的分組中
(?:pattern):非捕獲的分組,並未分組分配一個組號
(?>
pattern):貪婪分組
3,貪婪分組
貪婪分組也稱做非回溯分組,該分組禁用了回溯,正則表達式引擎將盡量多地匹配輸入文本中的字符。若是沒法進行進一步的匹配,則不會回溯嘗試進行其餘模式匹配。
(?> pattern )
4,二選一
| 的意思是或,匹配二者中的任意一個,注意,|把左右兩邊的表達式分爲兩部分。
pattern1 | pattern2
零寬是指寬度爲0,匹配的是位置,因此匹配的子串不會出如今匹配結果中,而斷言是指判斷的結果,只有斷言爲真,纔算匹配成功。
對於定位符,能夠匹配一句話的開始、結束(^ $)或者匹配一個單詞的開始、結束(\b),這些元字符只匹配一個位置,指定這個位置知足必定的條件,而不是匹配某些字符,所以,它們被成爲 零寬斷言。所謂零寬,指的是它們不與任何字符相匹配,而匹配一個位置;所謂斷言,指的是一個判斷,正則表達式中只有當斷言爲真時纔會繼續進行匹配。零寬斷言能夠精確的匹配一個位置,而不只僅是簡單的指定句子或者單詞。
正則表達式把文本看做從左向右的字符流,向右叫作後向(Look behind),向左叫作前向(Look ahead)。對於正則表達式,只有當匹配到指定的模式(Pattern)時,斷言爲True,叫作確定式,把不匹配模式爲True,叫作否認式。
按照匹配的方向和匹配的定性,把零寬斷言分爲四種類型:
(?=
pattern):前向、確定斷言
(?!
pattern):前向、否認斷言
(?<=
pattern):後向、確定斷言
(?<!
pattern):後向、否認斷言
1,前向確定斷言
前向確定斷言定義一個模式必須存在於文本的末尾(或右側),可是該模式匹配的子串不會出如今匹配的結果中,前向斷言一般出如今正則表達式的右側,表示文本的右側必須知足特定的模式:
(?=
subexpression)
使用前向確定斷言能夠定一個模糊匹配,後綴必須包含特定的字符:
\b\w+(?=\sis\b)
對正則表達式進行分析:
從分析中,能夠得出,匹配該正則表達式的文本中必須包含 is 單詞,is是一個單獨的單詞,不是某一個單詞的一個部分。舉個例子
Sunday is a weekend day 匹配該正則,匹配的值是Sunday,而The island has beautiful birds 不匹配該正則。
2,後向確定斷言
後向確定斷言定義一個模式必須存在於文本的開始(或左側),可是該模式匹配的子串不會出如今匹配的結果中,後向斷言一般出如今正則表達式的左側,表示文本的左側必須知足特定的模式:
(?<= subexpression )
使用後向確定斷言能夠定一個模糊匹配,前綴必須包含特定的字符:
(?<=\b20)\d{2}\b
對正則表達式進行分析:
該正則表達式匹配的文本具有的模式是:文本以20開頭、以兩個數字結尾。
有以下的JSON格式的文本,從文本中扣出字段(CustomerId、CustomerName、CustomerIdSource和CustomerType)的值:
{"CustomerDetails":"[{\"CustomerId\":\"57512f19\",\"CustomerName\":\"cust xyz\",\"CustomerIdSource\":\"AadTenantId\",\"CustomerType\":\"Enterprise\"}]"}
注意,該文本轉換爲C#中的字符時,須要對雙引號和轉義字符進行轉義。因爲這四個字段提取規則相同,能夠寫一個通用的模式來提取:
public static string GetNestedItem(string txt, string key) { string pat = string.Format("(?<=\\\\\"{0}\\\\\":\\\\\").*?(?=\\\\\")", key); return Regex.Match(txt, pat, RegexOptions.IgnoreCase).Value; }
正則表達式得解析:
注意:對於文本字段是\"abc\",使用C#字符串表示是\\\"abc\\\",這是由於原始字符串 \"是兩個字符,所以須要分別表示。
使用正則表達式表示是 \\\\\"abc\\\\\", 這是由於在正則表達式中,\ 是一個轉義字符,\\ 表示字符 \ 。
參考文檔:
Regular Expression Language - Quick Reference
原文出處:https://www.cnblogs.com/ljhdo/p/11912171.html