dart正則


1、前言

API中對於正則表達式的注釋是:
正則表達式的規范和語義與JavaScript相同
詳細的規范可以參考:http://ecma-international.org/ecma-262/5.1/#sec-15.1

打開鏈接,全英文的、、、瞄了一下
不明覺厲!!!

然后,花了一段時間對其支持的特性進行了測試
在附表中將Dart中正則表達式的特性列出來,簡單明了
以供大家參考

2、點號通配符

關於Dart中正則表達式支持的特性
越是深入了解,越是感覺復雜

附表中的內容可能不全,但基本上都有提及
這里需要注意其中的 . 點號通配符

通常,點號是不能匹配換行符的
這也使得 .* 表達式變得有些古怪
由於最初Unix正則表達式都是逐行處理的
所以可能后來新的語法是為了保證一致性吧!

但是在測試的時候,結果讓人有點頭大
例如,處理字符串 ABC\nDEF

import 'dart:io'; void main() { String str = "ABC\nDEF"; RegExp reg = new RegExp(r".*"); Iterable<Match> matches = reg.allMatches(str); for (Match m in matches) { print("${m.group(0).isEmpty ? "Match is Empty\nIndex is ${m.end}" : "Match is ${m.group(0)} \nAscii is ${m.group(0).codeUnits}\nIndex is ${m.end}"}"); print("--end--\n"); } }

運行結果:

Match is ABC Ascii is [65, 66, 67] Index is 3 --end-- Match is Empty Index is 3 --end-- Match is DEF Ascii is [68, 69, 70] Index is 7 --end-- Match is Empty Index is 7 --end--

通過分析,對於正則表達式 .*
共匹配有4個Match
分別是:ABC 空 DEF 空
匹配到字符串的 \n 的時候結束
這里 \n 並沒有被捕獲,而是捕獲位置
是不是有點像 $

那么我們來匹配一下 .*$
運行結果:

Match is DEF Ascii is [68, 69, 70] Index is 7 --end-- Match is Empty Index is 7 --end--

什么意思呢?
在匹配 .* 的時候,如果遇到 \n
處理方式和遇到 $ 一樣,停止“本行”匹配
但是不捕獲文本、、、有點繞

如果我們打開RegExp的multiLine開關,結果會怎么樣?
大家可以動手測試一下

new RegExp(".*", multiLine:true);

對於 .* 表達式,結果沒有任何變化
但是對於 .*$ ,結果此時和 .* 的結果一樣
也就是說,在打開multiLine開關的時候
如果表達式 .* 遇到 \n ,處理方式和遇到 $ 一樣
同時匹配之前的字符串、、、

如果我們想捕獲 \n 這個字符串的話,有辦法嗎?
在測試過后,得出結論
無論是否打開multiLine, .* 都不會匹配 \n 本身
但是,無論是否打開multiLine
[] 字符組和 [^] 排除型字符組都會匹配 \n 本身

可以試一下匹配 [^!]* ,運行結果如下:

Match is ABC DEF Ascii is [65, 66, 67, 10, 68, 69, 70] Index is 7 --end-- Match is Empty Index is 7 --end--

\n 的Ascii碼是10,結果沒有問題
\n 作為文本被捕獲,字符串結束的位置也被捕獲

如果說的不夠清楚,大家可以打開、關閉multiLine開關的情況下
分別測試如下表達式: ^.* 、 .*$ 、 ^.*$ ,然后體會一番

點號通配模式,也有個稱呼叫單行模式
在匹配多行文本的時候,需要特別注意
對最終結果還是影響很大的、、、

3、附表:Dart中正則表達式支持的特性

特性
描述
\
將下一個字符標記為一個特殊字符、或一個原義字符、或一個后向引用、或一個八進制轉義符。例如,”n”匹配字符”n”。”\n”匹配一個換行符。序列”\\”匹配”\”,”\(“則匹配”(“。
.
匹配任何單個字符。
^
匹配輸入字符串的開始位置。如果設置了RegExp 對象的Multiline屬性,^也匹配”\n”或”\r”之后的位置。例如,”^.”可以匹配”abc\n123″中的”a”和”1″。
$
匹配輸入字符串的結束位置。如果設置了RegExp對象的Multiline屬性,$也匹配 “\n” 或”\r”之前的位置。例如,”.$”可以匹配”abc\n123″中的”c”和”3″。
*
匹配前面的子表達式零次或多次。例如,”zo*”能匹配 “z”或”zoo”整個字符串。”*”等價於{0,}。
+
匹配前面的子表達式一次或多次。例如,”zo+” 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。”+”等價於{1,}。
? (限制符)
匹配前面的子表達式零次或一次。例如,”do(es)?” 可以匹配 “do” 或 “does”整個字符串。”?”等價於 {0,1}。
?(非貪婪模式)
當該字符緊跟在任何一個其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面時,匹配模式是非貪婪的。非貪婪模式盡可能少的匹配所搜索的字符串,而默認的貪婪模式則盡可能多的匹配所搜索的字符串。例如,對於字符串”oooo”,”o+?”將匹配單個”o”,而”o+”將匹配”oooo”。
x|y
匹配x或y。例如,”z|food”能匹配”z”或”food”。”(z|f)ood” 則匹配”zood”或”food”。
[xyz]
字符集合。匹配所包含的任意一個字符。例如,”[abc]” 可以匹配”plain”中的”a”。Dart中不支持字符組嵌套,如:[[a-z]&&[^b]]。
[^xyz]
排除字符集合。匹配未包含的任意字符。例如, “[^abc]” 可以匹配 “plain” 中的”p”。
[a-z]
字符范圍。匹配指定范圍內的任意字符。例如,”[a-z]”可以匹配”a”到”z”范圍內的任意小寫字母字符。
[^a-z]
排除字符范圍。匹配任何不在指定范圍內的任意字符。例如,”[^a-z]”可以匹配任何不在”a”到”z”范圍內的任意字符。
{n}
n 是一個非負整數。匹配確定的n次。例如,”o{2}”不能匹配”Bob”中的”o”,但是能匹配”food”中的”oo”。
{n,}
n 是一個非負整數。至少匹配n 次。例如,”o{2,}”不能匹配”Bob”中的”o”,但能匹配”fooood”中的”oooo”。”o{1,}”等價於”o+”。”o{0,}”則等價於”o*”。
{n,m}
m 和 n 均為非負整數,其中n <= m。最少匹配 n 次且最多匹配 m 次。劉, “o{1,3}” 將匹配 “fooood” 中的”ooo”和”o”。”o{0,1}”等價於”o?”。請注意在逗號和兩個數之間不能有空格。
(pattern)
匹配pattern 並獲取這一匹配。此時,整個表達式無論多復雜,都被視為一個單元。所獲取的匹配可以從產生的 Match對象的group(id) 得到。要匹配圓括號字符,請使用 ‘\(‘ 或 ‘\)’。
(?:pattern)
非匹配型括號。相比普通括號,非匹配型括號只分組不捕獲。這樣一是可以避免不必要的捕獲,提高效率,二是可以讓代碼可以更加清晰[例如,在捕獲字符串中某個名字的時候,可能是group(1)或2、3…使用非匹配型括號,可以僅返回group(1)]。
(?=pattern)
肯定順序環視。環視匹配的是特定位置,不匹配任何字符,也就是並不會“占用”字符。順序環視從左到右匹配表達式,如果能匹配,則返回匹配成功信息。
(?!pattern)
否定順序環視。從左到右匹配表達式,如果不能匹配,則返回匹配成功信息。
(?<=pattern)
肯定逆序環視,不支持。
(?<!pattern)
否定逆序環視,不支持。
(?>pattern)
固化分組,不支持。
(?if then |else)
條件判斷,不支持。
(?<name>pattern)
捕獲文本到命名組,不支持。
(?#text)
注釋,不支持。
\w
匹配包括下划線的任何單詞字符。等價於”[A-Za-z0-9_]”。
\W
匹配任何非單詞字符。等價於”[^A-Za-z0-9_]”。
\b
匹配單詞(\w+)的邊界(開始或末尾)。例如,對於字符串”never??!!”,”er\b”可以匹配”er”,”\bne”可以匹配”ne”。
\B
匹配單詞(\w+)的非末尾,對於非單詞(\W、\W+)字符沒有意義。例如,對於字符串”never??!!”,表達式”ev\B”能匹配”ev”;表達式”\?\B”能匹配兩個”?”,”\?!\B”能匹配”?!”,此時\B沒有意義。
\cx
匹配由x指明的控制字符。例如,\cM匹配Control+M,等價於\r,\cI匹配\t,\cJ匹配\n,。x的值必須為A-Z或a-z之一。否則,將c視為一個原義的”c”字符。
\d
匹配一個數字字符。等價於 [0-9]。
\D
匹配一個非數字字符。等價於 [^0-9]。
\f
匹配一個換頁符。等價於 \x0c 和 \cL。
\n
匹配一個換行符。等價於 \x0a 和 \cJ。
\r
匹配一個回車符。等價於 \x0d 和 \cM。
\s
匹配任何空白字符,包括空格、制表符、換頁符等等。等價於[ \f\n\r\t\v]。
\S
匹配任何非空白字符。等價於[^ \f\n\r\t\v]。
\t
匹配一個制表符。等價於 \x09 和 \cI。
\v
匹配一個垂直制表符。等價於 \x0b 和 \cK。
\<
匹配單詞開始位置,不支持。
\>
匹配單詞結束位置,不支持。
\xn
匹配n,其中n為十六進制轉義值。十六進制轉義值必須為確定的兩個數字長。例如,”\x41″匹配”A”。正則表達式中可以使用ASCII 編碼。
\int
反向引用,int為一個正整數。匹配之前獲取的、表達式匹配的文本。例如:”(a)(b)(c)\1\2\3″能夠匹配”abcabc”。“\”元字符中,優先級為:反向引用>八進制Ascii值>原義字符。
\oct
標識一個八進制轉義值或一個反向引用。如果之前至少 有otc個獲取的子表達式,則otc為后向引用。否則,如果otc為八進制數字 (0-7),則otc為一個八進制轉義值(具體查看ASCII 編碼)。
\nm
標識一個八進制轉義值或一個反向引用。如果 \nm 之前至少有nm個獲取得子表達式,則nm為反向引用。如果 \nm之前至少有n個獲取,則n為一個后跟文字m的反向引用。如果前面的條件都不滿足,若n和m均為八進制數字(0-7),則\nm將匹配八進制轉義值nm(具體查看ASCII 編碼)。
\nml
如果 n 為八進制數字 (0-3),且 m 和 l 均為八進制數字 (0-7),則匹配八進制轉義值 nml(具體查看ASCII 編碼)。例如,”\101″能夠匹配”A”。
\un
匹配n,其中n是一個用四個十六進制數字表示的 Unicode字符。例如,”\u00A9″匹配版權符號”©”。
[:flag:]
字符簇,如alnum、alpha、digit等,不支持。
\p{flag}
Unicode屬性、字母表和區塊,如InHanzi、Letter、Number等,不支持。
g、s、i、m、x、U
修飾符,用在正則表達式結尾,不支持。
區分大小寫
設置RegExp中可選參數為caseSensitive。
多行匹配
當匹配的字符串是多行的時候,可設置RegExp可選參數multiLine。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM