run(Subject, RE, Options) ->
{match, Captured} | match | nomatch | {error, ErrType}
Subject = iodata() | unicode:charlist()
RE = mp() | iodata() | unicode:charlist()
Options = [Option]
Option =
anchored | global | notbol | noteol | notempty |
notempty_atstart | report_errors |
{offset, integer() >= 0} |
{match_limit, integer() >= 0} |
{match_limit_recursion, integer() >= 0} |
{newline, NLSpec :: nl_spec()} |
bsr_anycrlf | bsr_unicode |
{capture, ValueSpec} |
{capture, ValueSpec, Type} |
CompileOpt
Type = index | list | binary
ValueSpec =
all | all_but_first | all_names | first | none | ValueList
ValueList = [ValueID]
ValueID = integer() | string() | atom()
CompileOpt = compile_option()
compile/2
.Captured = [CaptureData] | [[CaptureData]]
CaptureData =
{integer(), integer()} | ListConversionData | binary()
ListConversionData =
string() |
{error, string(), binary()} |
{incomplete, string(), binary()}
ErrType =
match_limit | match_limit_recursion | {compile, CompileErr}
CompileErr =
{ErrString :: string(), Position :: integer() >= 0}
執行正則表達式匹配,並返回 match/{match, Captured}
或 nomatch
。正則表達式可以指定為 iodata()
在這種情況下它會自動編譯(如 compile/2
)並執行,或者指定為預編譯的 mp()
在這種情況下它會直接針對主題執行。
涉及編譯時,如果出現編譯錯誤,會拋出異常badarg
。調用compile/2
以獲取有關正則表達式中錯誤位置的信息。
如果之前編譯過正則表達式,則選項列表隻能包含以下選項:
anchored
{capture, ValueSpec}/{capture, ValueSpec, Type}
global
{match_limit, integer() >= 0}
{match_limit_recursion, integer() >= 0}
{newline, NLSpec}
notbol
notempty
notempty_atstart
noteol
{offset, integer() >= 0}
report_errors
否則,也允許對函數 compile/2
有效的所有選項。允許編譯和執行匹配的選項,即 anchored
和 {newline,
NLSpec}
,如果與非預編譯的正則表達式一起存在,則會影響編譯和執行。
如果之前使用選項 unicode
編譯了正則表達式,則 Subject
將作為有效的 Unicode charlist()
提供,否則任何 iodata()
都可以。如果涉及編譯並且指定了選項unicode
,則Subject
和正則表達式都將被指定為有效的Unicode charlists()
。
{capture, ValueSpec}/{capture,
ValueSpec, Type}
定義成功匹配後函數返回的內容。 capture
元組可以包含值規範(告知要返回哪個捕獲的子字符串)和類型規範(告知如何返回捕獲的子字符串(作為索引元組、列表或二進製文件))。下麵詳細說明了這些選項。
如果捕獲選項說明不進行子字符串捕獲( {capture, none}
),則該函數在成功匹配時返回單個原子 match
,否則返回元組 {match, ValueList}
。可以通過指定 none
或將空列表指定為 ValueSpec
來禁用捕獲。
選項 report_errors
添加了返回錯誤元組的可能性。該元組或者指示匹配錯誤( match_limit
或 match_limit_recursion
),或者指示編譯錯誤,其中錯誤元組的格式為 {error, {compile,
CompileErr}}
。請注意,如果未指定選項 report_errors
,則該函數永遠不會返回錯誤元組,而是將編譯錯誤報告為 badarg
異常,並將由於超出匹配限製而失敗的匹配簡單地報告為 nomatch
。
以下選項與執行相關:
anchored
-
將
run/3
限製為在第一個匹配位置進行匹配。如果模式是使用anchored
編譯的,或者結果是憑借其內容進行錨定的,則無法在匹配時將其取消錨定,因此沒有unanchored
選項。 global
-
實現全局(重複)搜索(Perl 中的標誌
g
)。每個匹配項都作為單獨的list()
返回,其中包含特定匹配項和任何匹配子表達式(或由選項capture
指定)。因此,返回值的Captured
部分是list()
的list()
,當此選項已指定。選項
global
與匹配空字符串的正則表達式的交互讓一些用戶感到驚訝。當指定選項global
時,run/3
以與 Perl 相同的方式處理空匹配:也會使用選項[anchored, notempty_atstart]
重試任意點的零長度匹配。如果該搜索給出的結果長度 > 0,則包含該結果。例子:re:run("cat","(|at)",[global]).
執行以下匹配:
- At offset
0
-
正則表達式
(|at)
首先匹配字符串cat
的初始位置,給出結果集[{0,0},{0,0}]
(第二個{0,0}
是因為括號標記的子表達式)。由於比賽長度為 0,我們還沒有進入下一個位置。 - At offset
0
with[anchored, notempty_atstart]
-
使用選項
[anchored, notempty_atstart]
在同一位置重試搜索,這不會給出任何更長長度的有趣結果,因此搜索位置前進到下一個字符 (a
)。 - At offset
1
-
搜索結果為
[{1,0},{1,0}]
,因此也會使用額外選項重複此搜索。 - At offset
1
with[anchored, notempty_atstart]
-
找到替代方案
ab
,結果為 [{1,2},{1,2}]。結果將添加到結果列表中,並且搜索字符串中的位置將前進兩步。 - At offset
3
-
搜索再次匹配空字符串,給出
[{3,0},{3,0}]
。 - At offset
1
with[anchored, notempty_atstart]
-
這不會給出長度 > 0 的結果,並且我們位於最後一個位置,因此全局搜索已完成。
調用的結果是:
{match,[[{0,0},{0,0}],[{1,0},{1,0}],[{1,2},{1,2}],[{3,0},{3,0}]]}
- At offset
notempty
-
如果指定此選項,則空字符串不被視為有效匹配。如果模式中存在替代方案,則會嘗試它們。如果所有替代項都匹配空字符串,則整個匹配失敗。
例子:
如果以下模式應用於不以 "a" 或 "b" 開頭的字符串,它通常會匹配主題開頭的空字符串:
a?b?
使用選項
notempty
,此匹配無效,因此run/3
進一步在字符串中搜索 "a" 或 "b" 的出現。 notempty_atstart
-
與
notempty
類似,但允許不在主題開頭的空字符串匹配。如果模式是錨定的,則僅當模式包含 \K 時才會發生此類匹配。Perl 沒有直接等效於
notempty
或notempty_atstart
,但它確實在 split() 函數中以及使用修飾符/g
時對空字符串進行模式匹配。匹配空字符串後,可以通過首先在notempty_atstart
和anchored
相同的偏移量處再次嘗試匹配來模擬 Perl 行為,然後,如果失敗,則通過提前起始偏移量(見下文)並嘗試普通的再次比賽。 notbol
-
指定主題字符串的第一個字符不是行的開頭,因此其前麵的揚抑元字符不匹配。在沒有
multiline
(編譯時)的情況下設置此項會導致揚抑符永遠不會匹配。此選項僅影響揚抑符元字符的行為。它不影響\A。 noteol
-
指定主題字符串的結尾不是行的結尾,因此美元元字符不匹配它,也不匹配它之前的換行符(多行模式除外)。在沒有
multiline
(編譯時)的情況下設置此值會導致美元永遠不匹配。此選項僅影響美元元字符的行為。它不影響 \Z 或 \z。 report_errors
-
更好地控製
run/3
中的錯誤處理。指定後,編譯錯誤(如果尚未編譯正則表達式)和運行時錯誤將作為錯誤元組顯式返回。以下是可能的運行時錯誤:
match_limit
-
PCRE 庫對內部匹配函數的調用次數設置了限製。在為 Erlang 編譯的庫中默認為 10,000,000。如果返回
{error, match_limit}
,則正則表達式的執行已達到此限製。這通常被視為nomatch
,這是發生這種情況時的默認返回值,但通過指定report_errors
,當由於內部調用過多而導致匹配失敗時,您會收到通知。 match_limit_recursion
-
這個錯誤非常類似於
match_limit
,但是當 PCRE 的內部匹配函數 "recursively" 調用次數多於match_limit_recursion
limit,默認也是 10,000,000。請注意,隻要match_limit
和match_limit_default
值保留為默認值,match_limit_recursion
錯誤不會發生,因為match_limit
錯誤發生在這之前(每次遞歸調用也是一次調用,但反之則不然)。但是,這兩個限製都可以通過直接在正則表達式字符串中設置限製來更改(請參閱PCRE 正則表達式詳細信息)或通過指定選項run/3
.
重要的是要理解,限製匹配時所謂的 "recursion" 並不是 Erlang 機器的 C 堆棧或 Erlang 進程堆棧上的遞歸。編譯到 Erlang VM 中的 PCRE 版本使用機器 "heap" 內存來存儲必須在正則表達式匹配中的遞歸中保留的值。
{match_limit, integer() >= 0}
-
以特定於實現的方式限製匹配的執行時間。 PCRE文檔對其說明如下:
The match_limit field provides a means of preventing PCRE from using up a vast amount of resources when running patterns that are not going to match, but which have a very large number of possibilities in their search trees. The classic example is a pattern that uses nested unlimited repeats. Internally, pcre_exec() uses a function called match(), which it calls repeatedly (sometimes recursively). The limit set by match_limit is imposed on the number of times this function is called during a match, which has the effect of limiting the amount of backtracking that can take place. For patterns that are not anchored, the count restarts from zero for each position in the subject string.
這意味著如果使用此選項降低限製,失控的正則表達式匹配可能會失敗得更快。默認值 10,000,000 被編譯到 Erlang VM 中。
注意該選項絕不會影響 Erlang VM 的“長時間運行 BIF”的執行。
run/3
總是定期將控製權交還給 Erlang 進程的調度程序,以確保 Erlang 係統的實時性。 {match_limit_recursion, integer() >= 0}
-
以特定於實現的方式限製匹配的執行時間和內存消耗,與
match_limit
非常相似。 PCRE文檔對其說明如下:The match_limit_recursion field is similar to match_limit, but instead of limiting the total number of times that match() is called, it limits the depth of recursion. The recursion depth is a smaller number than the total number of calls, because not all calls to match() are recursive. This limit is of use only if it is set smaller than match_limit. Limiting the recursion depth limits the amount of machine stack that can be used, or, when PCRE has been compiled to use memory on the heap instead of the stack, the amount of heap memory that can be used.
Erlang VM 使用 PCRE 庫,當發生正則表達式匹配遞歸時,會使用堆內存。因此,這限製了機器堆的使用,而不是 C 堆棧。
指定較低的值可能會導致深度遞歸匹配失敗,而實際上它們應該匹配:
1> re:run("aaaaaaaaaaaaaz","(a+)*z"). {match,[{0,14},{0,13}]} 2> re:run("aaaaaaaaaaaaaz","(a+)*z",[{match_limit_recursion,5}]). nomatch 3> re:run("aaaaaaaaaaaaaz","(a+)*z",[{match_limit_recursion,5},report_errors]). {error,match_limit_recursion}
此選項和選項
match_limit
僅在極少數情況下使用。在篡改這些限製之前,建議先了解 PCRE 庫的內部結構。 {offset, integer() >= 0}
-
從主題字符串中指定的偏移(位置)開始匹配。偏移量從零開始,因此默認值為
{offset,0}
(所有主題字符串)。 {newline, NLSpec}
-
覆蓋主題字符串中換行符的默認定義,即 Erlang 中的 LF (ASCII 10)。
cr
-
換行符由單個字符 CR (ASCII 13) 指示。
lf
-
默認情況下,換行符由單個字符 LF (ASCII 10) 表示。
crlf
-
換行符由 two-character CRLF(ASCII 13 後跟 ASCII 10)序列指示。
anycrlf
-
可以識別前麵三個序列中的任何一個。
any
-
上麵的任何換行序列以及 Unicode 序列 VT(垂直製表符,U+000B)、FF(換頁符,U+000C)、NEL(下一行,U+0085)、LS(行分隔符,U+2028)、和 PS(段落分隔符,U+2029)。
bsr_anycrlf
-
特別指定 \R 僅匹配 CR LF 或 CRLF 序列,而不匹配 Unicode-specific 換行符。 (覆蓋編譯選項。)
bsr_unicode
-
特別指定 \R 匹配所有 Unicode 換行符(包括 CRLF 等,默認值)。 (覆蓋編譯選項。)
{capture, ValueSpec}
/{capture, ValueSpec, Type}
-
指定返回哪些捕獲的子字符串以及以什麽格式返回。默認情況下,
run/3
捕獲子字符串的所有匹配部分和所有捕獲子模式(所有模式都會自動捕獲)。默認返回類型是字符串的捕獲部分的(從零開始)索引,指定為{Offset,Length}
對(捕獲的index
Type
)。作為默認行為的示例,以下調用將主題的匹配部分(中間的"abcd")作為索引對
{3,4}
返回,作為第一個且唯一捕獲的字符串,其中字符位置從零開始,就像偏移量一樣:re:run("ABCabcdABC","abcd",[]).
該調用的返回值為:
{match,[{3,4}]}
另一種(而且很常見)的情況是正則表達式匹配所有主題:
re:run("ABCabcdABC",".*abcd.*",[]).
這裏的返回值相應地指出了從索引 0 開始的所有字符串,長度為 10 個字符:
{match,[{0,10}]}
如果正則表達式包含捕獲子模式,例如:
re:run("ABCabcdABC",".*(abcd).*",[]).
捕獲所有匹配的主題以及捕獲的子字符串:
{match,[{0,10},{3,4}]}
完整的匹配模式始終給出列表中的第一個返回值,其餘子模式按照它們在正則表達式中出現的順序添加。
捕獲元組的構建如下:
ValueSpec
-
指定要返回哪些捕獲的(子)模式。
ValueSpec
可以是說明一組預定義返回值的原子,也可以是包含要返回的特定子模式的索引或名稱的列表。以下是預定義的子模式集:
all
-
所有捕獲的子模式,包括完整的匹配字符串。這是默認設置。
all_names
-
全部命名為正則表達式中的子模式,就好像
list()
所有的名字按字母順序被指定。還可以使用以下命令檢索所有名稱的列表inspect/2
. first
-
僅第一個捕獲的子模式,它始終是主題的完整匹配部分。所有顯式捕獲的子模式都將被丟棄。
all_but_first
-
除第一個匹配子模式之外的所有子模式,即所有顯式捕獲的子模式,但不是主題字符串的完整匹配部分。如果正則表達式作為一個整體與主題的大部分相匹配,但您感興趣的部分位於顯式捕獲的子模式中,則這非常有用。如果返回類型是
list
或binary
,不返回您不感興趣的子模式是一個很好的優化方法。 none
-
不返回匹配的子模式,匹配成功時將單個原子
match
作為函數的返回值,而不是{match, list()}
返回。指定空列表會產生相同的行為。
值列表是要返回的子模式的索引列表,其中索引 0 表示所有模式,1 表示正則表達式中的第一個顯式捕獲子模式,依此類推。在正則表達式中使用命名的捕獲子模式(見下文)時,可以使用
atom()
或string()
來指定要返回的子模式。例如,考慮正則表達式:".*(abcd).*"
與字符串 "ABCabcdABC" 匹配,僅捕獲 "abcd" 部分(第一個顯式子模式):
re:run("ABCabcdABC",".*(abcd).*",[{capture,[1]}]).
該調用給出以下結果,因為第一個顯式捕獲的子模式是 "(abcd)",與主題中的 "abcd" 匹配,位於(從零開始)位置 3,長度為 4:
{match,[{3,4}]}
考慮相同的正則表達式,但子模式顯式命名為'FOO':
".*(?<FOO>abcd).*"
使用這個表達式,我們仍然可以通過以下調用給出子模式的索引:
re:run("ABCabcdABC",".*(?<FOO>abcd).*",[{capture,[1]}]).
給出與之前相同的結果。但是,當子模式被命名時,我們也可以在值列表中指定它的名稱:
re:run("ABCabcdABC",".*(?<FOO>abcd).*",[{capture,['FOO']}]).
這將產生與前麵的示例相同的結果,即:
{match,[{3,4}]}
值列表可以指定正則表達式中不存在的索引或名稱,在這種情況下,返回值根據類型而變化。如果類型為
index
,則對於正則表達式中沒有相應子模式的值,返回元組{-1,0}
,但對於其他類型(binary
和list
),值是空二進製或列表,分別。 Type
-
(可選)指定如何返回捕獲的子字符串。如果省略,則使用默認值
index
。Type
可以是以下之一:index
-
將捕獲的子字符串作為主題字符串的字節索引對和主題中匹配字符串的長度返回(就好像主題字符串被展平了一樣)iolist_to_binary(IoListOrBinary)或者
unicode:characters_to_binary/2
匹配之前)。注意該選項unicode
結果是麵向字節的a 中的索引(可能是虛擬的)UTF-8編碼二進製。字節索引元組{0,2}
因此可以代表一個或兩個字符unicode
已生效。這看起來counter-intuitive,但被認為是最有效和最有用的方法。如果需要的話,返回列表可以得到更簡單的代碼。此返回類型是默認值。 list
-
以字符列表的形式返回匹配的子字符串(Erlang
string()
s)。它選項unicode
與正則表達式中的 \C 序列結合使用,捕獲的子模式可以包含無效 UTF-8 的字節(\C 匹配字節,無論字符編碼如何)。在這種情況下list
捕獲可以產生相同類型的元組characters_to_list(Data, InEncoding)可以返回,即帶標簽的三元組incomplete
或者error
、成功轉換的字符以及轉換為二進製的無效 UTF-8 尾部。最好的策略是在捕獲列表時避免使用 \C 序列。 binary
-
以二進製形式返回匹配的子字符串。如果使用選項
unicode
,則這些二進製文件采用 UTF-8 格式。如果 \C 序列與unicode
一起使用,則二進製文件可能是無效的 UTF-8。
通常,當
type
為index
時,在匹配中未分配值的子模式將作為元組{-1,0}
返回。對於其他返回類型,未分配的子模式分別作為空二進製或列表返回。考慮以下正則表達式:".*((?<FOO>abdd)|a(..d)).*"
存在三個顯式捕獲子模式,其中左括號位置決定結果中的順序,因此
((?<FOO>abdd)|a(..d))
是子模式索引 1,(?<FOO>abdd)
是子模式索引 2,(..d)
是子模式索引 3。當與以下匹配時 String :"ABCabcdABC"
索引 2 處的子模式不匹配,因為字符串中不存在 "abdd" ,但完整模式匹配(因為替代
a(..d)
)。因此,索引 2 處的子模式未分配,默認返回值為:{match,[{0,10},{3,4},{-1,0},{4,3}]}
將捕獲
Type
設置為binary
給出:{match,[<<"ABCabcdABC">>,<<"abcd">>,<<>>,<<"bcd">>]}
這裏的空二進製文件 (
<<>>
) 表示未分配的子模式。在binary
情況下,有關匹配的一些信息因此丟失,因為<<>>
也可以是捕獲的空字符串。如果需要區分空匹配和不存在的子模式,請使用
type
index
並轉換為 Erlang 代碼中的最終類型。當指定選項
global
時,capture
規範會單獨影響每個匹配,因此:re:run("cacb","c(a|b)",[global,{capture,[1],list}]).
給
{match,[["a"],["b"]]}
有關僅影響編譯步驟的選項的說明,請參見compile/2
.
相關用法
- erlang reverse用法及代碼示例
- erlang rename用法及代碼示例
- erlang remove用法及代碼示例
- erlang registered用法及代碼示例
- erlang register用法及代碼示例
- erlang repair_continuation(Continuation, MatchSpec)用法及代碼示例
- erlang rootname(Filename)用法及代碼示例
- erlang raise(Class, Reason, Stacktrace)用法及代碼示例
- erlang register(RegName, PidOrPort)用法及代碼示例
- erlang registered()用法及代碼示例
- erlang round(Number)用法及代碼示例
- erlang read_file_info(Filename)用法及代碼示例
- erlang rand_seed()用法及代碼示例
- erlang read_file_info(File)用法及代碼示例
- erlang remove(Key, Map1)用法及代碼示例
- erlang referenced_byte_size(Binary)用法及代碼示例
- erlang replace(Subject, Pattern, Replacement, Options)用法及代碼示例
- erlang receive_response(RequestId, Timeout)用法及代碼示例
- erlang replace(String, SearchPattern, Replacement)用法及代碼示例
- erlang reverse(String :: unicode:chardata())用法及代碼示例
- erlang right(String, Number)用法及代碼示例
- erlang rstr(String, SubString)用法及代碼示例
- erlang rfc3339_to_system_time(DateTimeString)用法及代碼示例
- erlang reverse(List1, Tail)用法及代碼示例
注:本文由純淨天空篩選整理自erlang.org大神的英文原創作品 run(Subject, RE, Options) -> {match, Captured} | match | nomatch | {error, ErrType}。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。