1 定義

A regular expression, regex or regexp (sometimes called a rational expression) is a sequence of characters that define a search pattern. Usually this pattern is used by string searching algorithms for “find” or “find and replace” operations on strings, or for input validation. It is a technique that developed in theoretical computer science and formal language theory.

  • 如何把文字規律用某種標準格式表示的語法。

例如有一個檔案名稱叫:“Final107_1 410773118.Rmd”我們要電腦取出其中的學號410773118

方法一(非regular expression):用stringr::str_sub()取出第12-20位字元。

library(stringr)
"Final107_1 410773118.Rmd" %>%
  str_sub(12,20)

方法二(regular expression):

  1. 寫下你觀察到的規律: 一串數字;前面不是數字;而後面接著.Rmd

  2. 寫出其各自對應regex語法:[:digit:]+; (?<=[^[:digit:]]); (?=(.Rmd))

  3. 再依出現先後串接在一起:(?<=[^[:digit:]])[:digit:]+(?=(.Rmd))

"Final107_1 410773118.Rmd" %>%
  str_extract("(?<=[^[:digit:]])[:digit:]+(?=(.Rmd))")

依照stringr cheatsheet第二頁,

[:digit:] : 代表數字

[:digit:]+ : 代表數字「們」(見QUANTIFIERS

[^...]:代表「不是」(見ALTERNATES

[^[:digit:]] :代表「不是數字」

(?<=...):代表「前面接著」(見LOOK AROUNDS

(?<=[^[:digit:]]):代表「前面接的不是數字

(?=...):代表「後面接著」(見LOOK AROUNDS))

(?=(.Rmd)):代表「後面接著.Rmd字眼」

2 套件stringr

stringr套件裡有不少可以用regex處理文字的函數。

2.1 str_view_all

由於有時無法確定心中所想的regex是否會正確取出我們所要的文字區塊,這時str_view_all()非常好用。

str_view_all(要處理的文字, regex)

它會在螢幕上顯現「要處理的文字」,並把regex會選出來的區塊用陰影框起來。

例如:

"Final107_1 410773118.Rmd Final107_1-410773128.Rmd Final 410773006.Rmd" %>%
  str_view_all("(?<=[^[:digit:]])[:digit:]+(?=(.Rmd))")

滿意它選出來的結果,才進行文字粹取

"Final107_1 410773118.Rmd Final107_1-410773128.Rmd Final 410773006.Rmd" %>%
  str_extract_all("(?<=[^[:digit:]])[:digit:]+(?=(.Rmd))")

2.2 善用()形成字群

(見cheatsheet GROUPS

在前一節我們用了(?=(.Rmd)):代表「後面接著.Rmd字眼」,(.Rmd)要求要接的是完整的.Rmd,而不是只有.,.R.Rm。此外(...)也可以把要的文字特徵定義擴大。

例如: “桃園市8德區中華段40地號”,“彰化縣花壇鄉花壇段1418-0000地號” 要從中取出地號(含-

  1. 寫下你觀察到的規律: 一串數字-;後面接著「地號」

  2. 寫出其各自對應regex語法:([:digit:]|-)+; (?=(地號))

  3. 再依出現先後串接在一起:([:digit:]|-)+(?=(地號))

([:digit:]|-):代表要的文字特徵是數字或-,這裡「或」用|表示。透過()我們可以把特徵範圍群放大成數字及-。

([:digit:]|-)+:代表符合「數字、-」的「一串」字。

c("桃園市8德區中華段40地號"," 彰化縣花壇鄉花壇段1418-0000地號") %>%
  str_extract("([:digit:]|-)+(?=(地號))")

3 練習

以下每題都會產生兩個字串向量分別以xxx_from及xxx_to結尾,你必需要能用「一行」stringr裡的函數將from的內容轉成to的內容。注意只能一行,因為這是在訓練你是否能活用stringr套件及regular expression

3.1 1

stringrChallenge1_from <- read_csv("https://raw.githubusercontent.com/tpemartin/github-data/master/stringrChallenge1_from.csv")[[1]]
stringrChallenge1_to <- read_csv("https://raw.githubusercontent.com/tpemartin/github-data/master/stringrChallenge1_to.csv")[[1]]

3.2 2

使用str_extract_all()。中文字群的regex為[\\u4e00-\\u9fa5]

c("每週四3~4 社202","每週一5~7 法2F02","每週二5~7 商2F06 實習每週四5~6   商2F09")-> stringrChallenge2_from
stringrChallenge2_to<-
  list(
    c("3~4"),
    c("5~7"),
    c("5~7","5~6")
  )
stringrChallenge2_from %>%
  str_extract_all("([:digit:]|~){3}(?=\\s)")

3.3 3

使用str_extract_all()。中文字群的regex為[\\u4e00-\\u9fa5]

c("每週四3~4 社202","每週一5~7 法2F02","每週二5~7 商2F06 實習每週四5~6   商2F09")-> stringrChallenge3_from
stringrChallenge3_to<-
  list(
    c("每週四"),
    c("每週一"),
    c("每週二","每週四")
  )
stringrChallenge3_from %>%
  str_extract_all("[\\u4e00-\\u9fa5]{3}(?=[:digit:])")

3.4 4

使用str_extract_all()。中文字群的regex為[\\u4e00-\\u9fa5]

c("每週四3~4 社202","每週一5~7 法2F02","每週二5~7 商2F06 實習每週四5~6   商2F09")-> stringrChallenge4_from
stringrChallenge4_to<-
  list(
    c("每週四"),
    c("每週一"),
    c("每週二","實習每週四")
  )
stringrChallenge4_from %>%
  str_extract_all("[\\u4e00-\\u9fa5]{3,5}(?=[:digit:])")