中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
自學(xué)R語言(十三)-正則表達(dá)式的學(xué)習(xí)

正則表達(dá)式

正則表達(dá)式是對(duì)字符串類型數(shù)據(jù)進(jìn)行匹配判斷,提取等操作的一套邏輯公式。

處理字符串類型數(shù)據(jù)方面,高效的工具有Perl和Python。如果我們只是偶爾接觸文本處理任務(wù),則學(xué)習(xí)Perl無疑成本太高;如果常用Python,則可以利用成熟的正則表達(dá)式模塊:re庫;      如果常用R,則使用Hadley大神開發(fā)的stringr包則已經(jīng)能夠游刃有余。

正則表達(dá)式

“正則表達(dá)式是描述一組字符串特征的模式,用來匹配特定的字符串?!?br style="margin: 0px; padding: 0px;">—— Ken Thompson

上面的這句話已經(jīng)說明了什么是正則表達(dá)式。我把正則表達(dá)式看作一組有特殊語法的字符串,用來方便地從文本中匹配想要獲得的內(nèi)容。

R支持三種正則表達(dá)式模式:

1.默認(rèn)的是POSIX 1003.2 extended regular expressions。

2.通過設(shè)置參數(shù)perl=TRUE的方式使用Perl-like regular expressions。

3.通過設(shè)置參數(shù)fixed=TRUE的方式把正則表達(dá)式中的字符串視為其字面含義匹配。

如果已經(jīng)熟悉Perl語言的正則表達(dá)式,則可以跳過這一節(jié),直接了解R所提供的一些正則表達(dá)式的函數(shù)即可。

特殊字符

以下字符在正則表達(dá)式中不是其字面含義,是有特殊含義的:

\ | ( ) [ ] { } ^ $ * + ? .

要想在正則表達(dá)式中使用這些特殊字符的字面含義,需要在其前面加轉(zhuǎn)義符“\\”,例如想要匹配左側(cè)圓括號(hào)則使用“\\(”。需要注意的是,R中的正則表達(dá)式的轉(zhuǎn)義符需要兩個(gè)。

字符 含義
.      匹配除換行符 \n 之外的任何單個(gè)字符
-     連字符 當(dāng)且僅當(dāng)在字符組[]的內(nèi)部表示一個(gè)范圍,比如[A-Z]
|     或(or)
( )      表示一個(gè)字符組,括號(hào)內(nèi)的字符串將作為一個(gè)整體被匹配
[ ]      括號(hào)內(nèi)的任意字符將被匹配
{ }     包含指示出現(xiàn)次數(shù)上下限的數(shù)值
/       正則表達(dá)式模式的開始或結(jié)尾
\     轉(zhuǎn)義符

匹配字符串的邊界,如字符串的開頭、字符串的結(jié)尾、單詞邊界等。

字符含義
^字符串的開頭
$字符串的結(jié)尾
\\b英文單詞的邊界(perl模式)
\\B非英文單詞的邊界(perl模式)

注:將 ^ 用作括號(hào)[]表達(dá)式中的第一個(gè)字符,則會(huì)對(duì)字符集求反

量詞

量詞放在字符的后面,來控制前面字符出現(xiàn)的次數(shù)。

字符含義
*匹配0次或更多次 {0,}
+匹配1次或更多次 {1,}
?匹配0次或1次   {0,1}
{N}匹配N次
{N,}至少匹配N次
{N,M}至少匹配N次,但不超過M次

默認(rèn)的情況下,這些量詞都是貪婪的,它們試圖匹配盡可能多的字符。要想讓它們匹配盡可能少的字符,則可以在量詞后加”?”來實(shí)現(xiàn)。舉例來說,在正則表達(dá)式“e+”,會(huì)匹配到字符串“beef”中的“ee”,而“e+?”,會(huì)分別匹配到其中的兩個(gè)“e”,作為兩次獨(dú)立的匹配。

字符類

字符類表示一類字符的集合,如“[abc]”表示a或b或c,使用“[]”把一些字符括起來代表其中的任意字符。除了“[]”之外,還有兩個(gè)特殊的字符“^”和“-”:

字符在字符類中的含義
^若出現(xiàn)在類的開頭,表示非此類中的字符
-若不出現(xiàn)在類的開頭和結(jié)尾,表示一個(gè)范圍,從“-”之前的字符到“-”之后的字符

常用的字符類及其簡稱:

R默認(rèn)正則簡稱Perl正則字符類含義
[[:digit:]]\\d[0-9]數(shù)字
[^[:digit:]]\\D[^0-9]非數(shù)字
[[:alpha:]][a-zA-Z][a-zA-Z]英文字母
[[:alnum:]][a-zA-Z\\d][a-zA-Z0-9]英文字母或數(shù)字
[[:blank:]][ \\t][ \\t]空格、tab
[[:space:]]\\s[ \\t\\r\\n\\f\\v]空白字符
[^[:space:]]\\S[^ \\t\\r\\n\\f\\v]非空白字符
 \\w[a-zA-Z0-9_]任意單詞字符
 \\W[^a-zA-Z0-9_]任意非單詞字符

分組及向后引用

“()”用來分組,并可以使用后向引用“\\1”、“\\2”等來引用第一個(gè)括號(hào)中匹配到的內(nèi)容、第二個(gè)括號(hào)中匹配到的內(nèi)容等。例如,正則表達(dá)式“(a)(b)\\1”等價(jià)于正則表達(dá)式“aba”。

需要注意的是若在括號(hào)內(nèi)的開頭出現(xiàn)“?:”,則此分組不編號(hào),不可引用。例如,正則表達(dá)式“(?:a)(b)\\1”等價(jià)于正則表達(dá)式“abb”。

代表字符組的特殊符號(hào)

代碼含義說明
\w字符串,等價(jià)于[:alnum:]
\W非字符串,等價(jià)于[^[:alnum:]]
\s空格字符,等價(jià)于[:blank:]
\S非空格字符,等價(jià)于[^[:blank:]]
\d數(shù)字,等價(jià)[0-9]
\D非數(shù)字,等價(jià)于[^0-9]
\bWord edge(單詞開頭或結(jié)束的位置)
\BNo Word edge(非單詞開頭或結(jié)束的位置)
\<Word beginning(單詞開頭的位置)
\>Word end(單詞結(jié)束的位置)

匹配

R-base提供了grep,grepl,regexpr和regexec四個(gè)函數(shù)從字符串向量中提取符合正則表達(dá)式的匹配結(jié)果。它們的區(qū)別主要在返回的結(jié)果上。
這幾個(gè)函數(shù)的兩個(gè)主要參數(shù):

  • pattern: 正則表達(dá)式
  • x/text: 待匹配的字符串或字符串向量
y1 = "Li lei likes Han meimei."y2 = "David likes Han meimei."y = c(y1, y2)y1y2ygrep(pattern="Li lei", x=y1)## [1] 1grep(pattern="Li lei", x=y2)## integer(0)grepl(pattern="Li lei", x=y1)## [1] TRUEgrepl(pattern="Li lei", x=y2)## [1] FALSEgrep(pattern="Li lei", x=y)## [1] 1grepl(pattern="Li lei", x=y)## [1]  TRUE FALSEregexpr(pattern='l', text=y1)## [1] 4## attr(,"match.length")## [1] 1## attr(,"useBytes")## [1] TRUEgregexpr(pattern='l', text=y1)## [[1]]## [1] 4 8## attr(,"match.length")## [1] 1 1## attr(,"useBytes")## [1] TRUEregexec(pattern='l', text=y1)## [[1]]## [1] 4## attr(,"match.length")## [1] 1regexpr(pattern='l', text=y)## [1] 4 7## attr(,"match.length")## [1] 1 1## attr(,"useBytes")## [1] TRUEgregexpr(pattern='l', text=y)## [[1]]## [1] 4 8## attr(,"match.length")## [1] 1 1## attr(,"useBytes")## [1] TRUE## ## [[2]]## [1] 7## attr(,"match.length")## [1] 1## attr(,"useBytes")## [1] TRUEregexec(pattern='l', text=y)## [[1]]## [1] 4## attr(,"match.length")## [1] 1## ## [[2]]## [1] 7## attr(,"match.length")## [1] 1

默認(rèn)情況下,grep返回匹配到的字符串在字符串向量x中的下標(biāo)位置,沒有匹配到結(jié)果時(shí)返回integer(0);grepl返回與x等長的logical向量,表示是否與pattern匹配。

regexpr返回與text等長的integer向量,表示第一個(gè)匹配pattern的起始位置,-1表示不匹配,屬性match.length表示對(duì)應(yīng)匹配的匹配長度。

gregexpr返回與text等長的列表,列表的每個(gè)元素是相應(yīng)字符串的匹配結(jié)果。與regexpr不同的是,gregexpr會(huì)在字符串中找到所有匹配的子串并把結(jié)果返回,稱之為全局匹配。

regexec返回與text等長的列表,列表的每個(gè)元素是相應(yīng)字符串的匹配結(jié)果。與regexpr相同,regexec只返回第一個(gè)匹配到的結(jié)果。

大小寫敏感:

參數(shù)ignore.cases用來控制正則匹配時(shí)是否是大小寫敏感的,默認(rèn)是大小寫敏感的。

grep(pattern='li lei', x=y, ignore.case = TRUE)## [1] 1grepl(pattern='li lei', x=y, ignore.case = TRUE)## [1]  TRUE FALSE

返回匹配到的整個(gè)字符串:

grep函數(shù)可以通過設(shè)置參數(shù)value=TRUE,直接返回匹配到的整個(gè)字符串。

grep(pattern='Li lei', x=y, value=TRUE)## [1] "Li lei likes Han meimei."

不匹配pattern:

grep函數(shù)的參數(shù)invert用來控制返回的結(jié)果是匹配正則表達(dá)式的或不匹配正則表達(dá)式的結(jié)果。默認(rèn)invert=FALSE,返回的是匹配正則表達(dá)式的結(jié)果;當(dāng)invert=TRUE時(shí),返回的是不匹配正則表達(dá)式的結(jié)果。

grep(pattern='Li lei', x=y, invert = TRUE)## [1] 2

提取

在R中,提取符合pattern的子字符串需要經(jīng)過兩個(gè)步驟:先使用regexpr / gregexpr/regexec匹配,再使用regmatches提取。
regmatches的兩個(gè)主要參數(shù):

  • x: 待匹配的字符串
  • m: regexpr / gregexpr/regexec對(duì)字符串x返回的匹配結(jié)果
s = 'aababaaaba'# 返回第一個(gè)匹配的部分m = regexpr(pattern='a+', text=s)regmatches(x=s, m)## [1] "aa"# 返回每一個(gè)匹配的部分mg = gregexpr(pattern='a+', text=s)regmatches(x=s, mg)## [[1]]## [1] "aa"  "a"   "aaa" "a"# 返回第一個(gè)匹配的部分m = regexec(pattern='a+', text=s)regmatches(x=s, m)## [[1]]## [1] "aa"

替換

R-base提供了兩個(gè)替換子字符串的函數(shù)sub和gsub。把目標(biāo)字符串中與pattern匹配的部分用replacement代替。這兩個(gè)函數(shù)的不同之處在于gsub會(huì)把目標(biāo)字符串中所有與pattern匹配的部分用replacement代替。

sub(pattern='Li lei', replacement='Xiao ming', x=y)## [1] "Xiao ming likes Han meimei." "David likes Han meimei."gsub(pattern='l', replacement='L', x=y)## [1] "Li Lei Likes Han meimei." "David Likes Han meimei."

拆分字符串

strsplit函數(shù)可以使用正則表達(dá)式作為拆分標(biāo)志來把字符串拆分成向量。需要注意的是strsplit返回的是列表。

# 目標(biāo)字符串中的數(shù)字使用不定個(gè)數(shù)的空白分隔開strsplit('1  2 3  4', '\\s+')## [[1]]## [1] "1" "2" "3" "4"# unlist可以去掉list結(jié)構(gòu)unlist(strsplit('1  2 3  4', '\\s+'))## [1] "1" "2" "3" "4"

舉一個(gè)例子:

strings <- c(  "apple",   "219 733 8965",   "329-293-8753",   "Work: 579-499-7527; Home: 543.355.3679")phone <- "([0-9]{2})[- .]([0-9]{3})[- .]([0-9]{4})"

在上面的代碼中,變量strings里保存的是一個(gè)字符串向量,我們的目標(biāo)是想檢驗(yàn)該向量中的每一個(gè)字符串是否包含有電話號(hào)碼。顯然,直接精確搜索是不可能的,因?yàn)槊總€(gè)電話號(hào)碼的內(nèi)容不盡相同。但是由于電話號(hào)碼都有相似的格式,這時(shí)候正則表達(dá)式就派上了用處。

我們定義了一個(gè)正則表達(dá)式phone,就是為了抓取這樣的格式:[0-9]表示我門要匹配一個(gè)數(shù)字,用花括號(hào){2}則表示[0-9]重復(fù)兩次,即開頭有兩個(gè)數(shù)字,[- .]表示數(shù)字之間的分隔符可以“-”也可以是“ ”和“.”。

最終我們用grep函數(shù)就可以得到如下結(jié)果:

> grep(phone,strings)[1] 2 3 4

這個(gè)函數(shù)的意思是用在strings里用phone所保存的正則表達(dá)式進(jìn)行匹配。顯然第一個(gè)字符串中沒有包含電話號(hào)碼,而其后三個(gè)字符串都是有電話的,這和strings變量保存的實(shí)際情況相符。

通過這個(gè)例子,相信大家對(duì)正則表達(dá)式已經(jīng)有了初步的理解,下面就歸納一些正則表達(dá)式的常用寫法:

1.匹配字符串:

首先,一個(gè)括號(hào)代表匹配一個(gè)位置, 想匹配某個(gè)字母就可以用把該字符寫到括號(hào)里,多個(gè)括號(hào)連在一起就可以匹配一個(gè)字符串:

比如[a]表示匹配字符'a',同理[\]表示匹配字符‘\’[c][a][t]表示匹配"cat"字符串當(dāng)然實(shí)際上如果只是匹配一個(gè)字符,完全可以不用中括號(hào),直接寫出cat就好

中括號(hào)在下列情況下才是必須要加的:即有時(shí)候在某一位置可能會(huì)出現(xiàn)幾種可能的字符。這時(shí)我們便將這些字符都寫入一個(gè)括號(hào)中,表達(dá)一種“或”的關(guān)系。

比如[aoeiu]就表示匹配'a'或'o'或'i'或'o'或'u',也就是表示匹配一個(gè)元音字母同理[0-9]表示匹配0-9之間的任何一個(gè)數(shù),也就是表示匹配一個(gè)數(shù)字[0123456789]也可以簡寫為[0-9],于是匹配一個(gè)年份就可以寫成[0-9][0-9][0-9][0-9]

[0-9]這種寫法顯然就比[0123456789]更為簡明,這在正則表達(dá)式里非常常見,字母也可以這樣寫:

[d-f]表示匹配'd'或'e'或'f'值得注意的是,正則表達(dá)式是區(qū)分大小寫的,于是[D-F]表示匹配'D'或'E'或'F'如果想匹配任意一個(gè)大寫字母就可以寫成[A-Z]如果相匹配任意一個(gè)字母就可以寫成[a-zA-Z]

此外我們還需知道'.','^',等特殊字符的用法:

'.'表示匹配任何一個(gè)字符,即通配符于是[....]就表示匹配任何一個(gè)長度為4的字符串,或者直接用....'^'表示“非”,就是表示對(duì)后面內(nèi)容的否定,即不包含哪個(gè)字符比如[^0-9]就表示除了數(shù)字之外的任何字符

還有幾種特殊的字母,也是為了方便大家使用:

比如\\d等價(jià)為[0-9],即任何一個(gè)數(shù)字,[0-9][0-9][0-9][0-9]也可寫為dddd\w等價(jià)為[^0-9a-zA-Z],即非數(shù)字非字母的任何一個(gè)字符\s等價(jià)為[.]即任何一個(gè)字符

現(xiàn)在我們做一個(gè)練習(xí),如果我們想匹配2016-10-18這種形式的日期格式,我們應(yīng)該用什么樣的正則表達(dá)式呢?

如果仔細(xì)閱讀了以上的內(nèi)容,相信這個(gè)不是很難,應(yīng)為如下:

[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]或者dddd-dd-dd

然而這樣寫是不是還是太繁瑣了呢?如果我要匹配36個(gè)連續(xù)的數(shù)字,難道也把[0-9]或者'd'復(fù)制36遍嗎?

其是我們完全可以用花括號(hào)內(nèi)的數(shù)字告訴正則表達(dá)式我們想要重復(fù)的次數(shù),用下列方式實(shí)現(xiàn):

[0-9]{4}-[0-9]{2}-[0-9]{2}或d{4}-d{2}-d{2}實(shí)現(xiàn)

這樣是不是就簡單多了?

花括號(hào)里也不僅僅只能是一個(gè)數(shù)字,還有其他用法:

比如a{2,6}就表示匹配"aa"或"aaaaaa"a{2-4}就表示匹配"aa","aaa","aaaa"colou{0,1}r就表示匹配"color","colour"

更為精妙的,花括號(hào)內(nèi)的數(shù)字可以是開區(qū)間:

a{2,}表示匹配連續(xù)次數(shù)兩次以上的'a',即"aa","aaa","aaaa"....{0,}表示匹配任何文本,因?yàn)檫@是一個(gè)通配符'.'重復(fù)任何次數(shù),由于我們是從0到正無窮,所以即便是一個(gè)空文本也可以被匹配到我們利用上面的寫法就可以輕松匹配到一對(duì)雙引號(hào)及里面的文本:".{0,}"但是上述寫法可能匹配到 "sdf"sdf"sdf"這樣的文本,即雙引號(hào)里還有雙引號(hào)。這時(shí)候我們可以用"[^"]{0,}"保證找到的雙引號(hào)里面沒有包括其他任何雙引號(hào);此外我們還可以用".*?"實(shí)現(xiàn)上述效果。本來".*?"中'.*'表示任何文本,但在其之后加上'?'之后就表示匹配最少的字符,故而就不會(huì)出現(xiàn)匹配的雙引號(hào)里文本還具有雙引號(hào)的問題了。

正則表達(dá)式提供了一些字符刻畫常見的花括號(hào)區(qū)間方法,比如:

'*'表示{0,},于是任何文本也可以通過".*"匹配'?'表示{0,1},比如colou?r也可以匹配"color","colour"'+'表示{1,},于是匹配一個(gè)及以上的 數(shù)字可以用d+

其他:

cat|dog可以表示匹配"cat"或"dog"Mon|Tues|Wednes|Thurs|Fri|Satur|Sun|day表示匹配一周內(nèi)任何一天 

2.匹配段落:

^表示匹配行的開始位置$表示匹配行的結(jié)束位置^&表示一個(gè)空行^.*& 表示匹配全文內(nèi)容,因?yàn)樾械拈_始符號(hào)也是一個(gè)字符,"."會(huì)匹配這個(gè)符號(hào)。找到單獨(dú)的一行,可以使用 ^.*?$

3.正則表達(dá)式函數(shù)

3.1 grep()

我們之前使用了一個(gè)正則表達(dá)式函數(shù)grep(),下面就細(xì)細(xì)講講正則表達(dá)式函數(shù):

text = c("to be", "or not to", "be it is", "a question")pat = "be"grep(pat, text)

這個(gè)函數(shù)很簡單,結(jié)果如下:

> grep(pat, text)[1] 1 3

返回的是一個(gè)向量,告訴我們原字符串的哪些下標(biāo)的字符串匹配成功了。

我們也可以加一個(gè)value屬性,返回的就是被匹配到的字符串組成的向量了。

> grep(pat, text, value=TRUE)[1] "to be"    "be it is"

此外,用invert屬性可以返回沒有被匹配到的下標(biāo)向量:

> grep(pat, text, invert = TRUE)[1] 2 4

3.2 grepl()

> grepl(pat, text)[1]  TRUE FALSE  TRUE FALSE

這個(gè)函數(shù)返回的是邏輯向量

3.3 regexpr()

> regexpr(pat, text)[1]  4 -1  1 -1attr(,"match.length")[1]  2 -1  2 -1attr(,"useBytes")[1] TRUE

這個(gè)函數(shù)返回前兩行表示匹配部分在字符串中的起始位置與長度,-1表示未匹配到。因?yàn)槲覀兤ヅ涞氖?be"在"to be"中就是第四個(gè)位置開始匹配,然后持續(xù)兩個(gè)長度,也就是返回值里的前兩行第一個(gè)下標(biāo)位置的返回值4和2。

3.4 gregexpr(pat, text)

> gregexpr(pat, text)[[1]][1] 4attr(,"match.length")[1] 2attr(,"useBytes")[1] TRUE[[2]][1] -1attr(,"match.length")[1] -1attr(,"useBytes")[1] TRUE[[3]][1] 1attr(,"match.length")[1] 2attr(,"useBytes")[1] TRUE[[4]][1] -1attr(,"match.length")[1] -1attr(,"useBytes")[1] TRUE

這個(gè)函數(shù)和上一個(gè)regexpr()很相似,只不過返回的是一個(gè)list。

模式替換與拆分函數(shù)

在這里我不會(huì)講R語言的自帶模式替換與拆分,因?yàn)樵谙缕恼吕镂視?huì)介紹stringr這個(gè)字符串處理的神包。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
R語言中正則表達(dá)式
在R語言中使用正則表達(dá)式
R正則表達(dá)式
【Python爬蟲學(xué)習(xí)筆記(2)】正則表達(dá)式(re模塊)相關(guān)知識(shí)點(diǎn)總結(jié)
Py之re:re正則表達(dá)式庫的簡介、入門、使用方法之詳細(xì)攻略
搞清楚 Python 正則表達(dá)式,簡單易懂看這一篇就夠了
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服