7 字串處理

(投影片 / 程式碼 / 影片)

7.1 Regular Expression (✍️)

7.1.1 Basics: ., ^, $, |, \ (escape)

  • .: 萬用字元

    妹妹.正
    妹妹很正
    妹妹超正
    我妹妹超級正
    妹妹 正
    妹妹..正
    我妹妹很正
    我妹妹超正
    妹妹超級正
    我妹妹 正
  • ^, $: Anchors

    ^你
    妹妹很正
    我妹妹超正
    沒有妹妹
    超正$
    你妹妹很正
    我妹妹超正
    你沒有妹妹
  • (), |: group

    gre|ay
    grey
    gray
    gr(e|a)y
    grey
    gray
    (很|超|超級)正
    我妹妹很正
    我妹妹超正
    我妹妹超級正
  • \: escape

    妹妹超\.級\.正
    妹妹超.級.正
    我妹妹超~級~正

7.1.2 Repetition

  • +, ?

    超+正
    我妹妹超正
    我妹妹超級正
    我妹妹超超超超正
    超級?正
    我妹妹超正
    我妹妹超級正
    我妹妹超超超超正
    超+級?正
    我妹妹超正
    我妹妹超級正
    我妹妹超超超超正
  • {num}, {min,}, {,max}, {min,max}

    \d{4}-\d{2}-\d{2}
    今天是 2019-10-31
    今天是 2019-2-10
    今天是 2019-1-1
    \d{4}-\d{1,2}-\d{1,2}
    今天是 2019-10-31
    今天是 2019-2-10
    今天是 2019-1-1
    \d{4}-\d{1,}-\d{1,}
    今天是 2019-1-10
    不存在 2019-555-555

7.1.3 Character classes

  • \s

    妹妹\s超正
    我妹妹超正
    1 space: 我妹妹 超正
    1 tab: 我妹妹 超正
    2 tabs: 我妹妹 超正
    妹妹\s+超正
    我妹妹超正
    妹妹 超正
    妹妹 超正
    妹妹 超正
  • []

    [超很極]正
    我妹妹超正
    我妹妹很正
    我妹妹極正
    我妹妹不正
    [B-D]1
    A1 B1 C1 D1 E1 F1 G1 H1 I1 J1 K1 L1 M1 N1 O1 P1 Q1 R1 S1 T1 U1 V1 W1 X1 Y1 Z1
    a[2-5]
    a1 a2 a3 a4 a5 a6 a7 a8 a9 a10
    a[^2-5]
    a1 a2 a3 a4 a5 a6 a7 a8 a9 a10

7.1.4 Your Turn

  1. 找出所有記者姓名

    【.{3}╱.+報導】
    【賴德剛╱綜合報導】
    大聯盟勞資協議昨獲共識,要繳交超出部分的17.5%稅額,連續第2年則課30%,連續第3年40%,第4年起都是50%。新版協議,第1年稅額調高為20%,第2年不變,第3年起都是50%。
    【曾雪蒨╱台中報導】
    一名35歲OL是「3C控」,白天上班打電腦、訊軟體聲響,竟忍不住低頭滑手機看內容...
    【蔡裕隆╱彰化報導】
    台灣啤酒「台版天兵麥基(JaVale McGee)」周伯勳,昨出戰臺灣銀行,轟出全隊次高...
    【韓政燕╱綜合外電報導】
    日本前晚從鹿兒島縣種子島宇宙中心成功發射搭載無人補給太空船「鸛」6號的...
    【國際中心╱綜合外電報導】
    今年美國總統大選期間,大量假新聞充斥推特、臉書等社交網站,遭質疑扭曲真相...
    【鍾裕能╱綜合報導】
    巨人季後簽了陽岱鋼、山口俊、森福允彥共3名自由球員,又網羅前樂天大砲...
  2. 找出所有百分比 (e.g. 20%, 17.5%)

    [0-9.]+%
    【賴德剛╱綜合報導】
    大聯盟勞資協議昨獲共識,要繳交超出部分的17.5%稅額,連續第2年則課30%,連續第3年40%,第4年起都是50%。新版協議,第1年稅額調高為20%,第2年不變,第3年起都是50%。
    【曾雪蒨╱台中報導】
    一名35歲OL是「3C控」,白天上班打電腦、訊軟體聲響,竟忍不住低頭滑手機看內容...
    【蔡裕隆╱彰化報導】
    台灣啤酒「台版天兵麥基(JaVale McGee)」周伯勳,昨出戰臺灣銀行,轟出全隊次高...
    【韓政燕╱綜合外電報導】
    日本前晚從鹿兒島縣種子島宇宙中心成功發射搭載無人補給太空船「鸛」6號的...
    【國際中心╱綜合外電報導】
    今年美國總統大選期間,大量假新聞充斥推特、臉書等社交網站,遭質疑扭曲真相...
    【鍾裕能╱綜合報導】
    巨人季後簽了陽岱鋼、山口俊、森福允彥共3名自由球員,又網羅前樂天大砲...

7.1.5 Backreference

(.)..\1
防不勝防
精益求精
眉下添眉
年復一年
噩噩渾渾
沸沸揚揚
紛紛攘攘
風風雨雨
(.)\1(.)\2
防不勝防
精益求精
眉下添眉
年復一年
噩噩渾渾
沸沸揚揚
紛紛攘攘
風風雨雨

7.1.6 Your Turn

一(.{1,2})接著?又?一\1
一口接一口
一口接著一口
一口接著又一口
一巴掌接著一巴掌

7.2 stringr

  • stringr 套件是 tidyverse 裡面用來處理字串的套件,比起 base R 的字串處理函數,stringr 中的函數在命名上相當一致 (str_*)、函數名稱也較「透明」因此比較容易記得。

  • 在 R 裡面,Regular Expression 是以字串的資料類型 (i.e. character) 去表徵,因此有一點需特別注意:

    若 Regular Expression 裡面出現反斜線,則在將此 Regex 寫進 R 的函數時,需要在每一個反斜線之前再加上一個反斜線

    • Regular Expression: today\.$

      today\.$
      It is sunny today.
    • Regular Expression in R function: "today\\.$"

      library(stringr)
      str_view("It is sunny today.", "today\\.$")

7.2.1 str_detect()

s <- c("cat", "bed", "car", "Mr.")
str_detect(s, "a")
#> [1]  TRUE FALSE  TRUE FALSE
str_detect(s, "\\.")
#> [1] FALSE FALSE FALSE  TRUE

7.2.2 str_match() / str_match_all()

  • str_match() 可從文字裡抓出符合 RegEx 的字串。str_match() 只會抓出 str 每個元素裡第一個符合的字串,並且以 matrix 的資料結構回傳:

    s <- c("Won't match.", 
           "One two three, four five six.", 
           "Seven eight nine.")
    str_match(s, "([a-zA-Z]+) ([a-zA-Z]+) ([a-zA-Z]+)")
    #>      [,1]               [,2]    [,3]    [,4]   
    #> [1,] NA                 NA      NA      NA     
    #> [2,] "One two three"    "One"   "two"   "three"
    #> [3,] "Seven eight nine" "Seven" "eight" "nine"
    • 回傳的 matrix 中,
      • 每列 (row) 對應到 str 中的一個元素。在此,因為 str 長度為 3,因此回傳的 matrix 有 3 列。matrix 的每列代表 str 中每個元素 (字串) 中第一個符合 RegEx 的部份。
      • 第一行 (column) 是整個 RegEx 抓到的字串,i.e. 符合 (\w+) (\w+) (\w+) 的字串。後面幾行依序是 RegEx 中,各個 group 所抓到的字串,i.e. 各個 () 裡的 RegEx。例如,第二行是第一個 (\w+) 所抓到的內容;第三行則是第二個 (\w+) 所抓到的內容;依此類推。
  • 若要抓出所有符合的字串,需使用 str_match_all()22str_match_all() 會抓出 str 每個元素裡所有符合的字串,並以 list 的資料結構回傳:

    str_match_all(s, "([a-zA-Z]+) ([a-zA-Z]+) ([a-zA-Z]+)")
    #> [[1]]
    #>      [,1] [,2] [,3] [,4]
    #> 
    #> [[2]]
    #>      [,1]            [,2]   [,3]   [,4]   
    #> [1,] "One two three" "One"  "two"  "three"
    #> [2,] "four five six" "four" "five" "six"  
    #> 
    #> [[3]]
    #>      [,1]               [,2]    [,3]    [,4]  
    #> [1,] "Seven eight nine" "Seven" "eight" "nine"
    • 回傳的 list 中,list 的每個元素依序對應到 str 的每個元素。因此,回傳的 list 長度為 3 (與 str 相同)
      • list 的每個元素內儲存的是一個 matrix,這個 matrix 的每列 (row) 對應到一個符合 RegEx 的字串。每行 (column) 的意義則與 str_match() 回傳的 matrix 相同。

7.4 相關資源