R中的Regex
阅读原文时间:2023年07月13日阅读:1

Description

grep、grepl、regexpr、gregexpr和regexec在字符向量的每个元素中搜索与参数模式匹配的参数:它们在结果的格式和详细程度上有所不同。

sub和gsub分别替换第一个匹配项和所有匹配项。

Usage

  • grep(pattern, x, ignore.case = FALSE, perl = FALSE, value = FALSE, fixed = FALSE, useBytes = FALSE, invert = FALSE)
  • grepl(pattern, x, ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE)
  • regexpr(pattern, text, ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE)
  • gregexpr(pattern, text, ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE)
  • regexec(pattern, text, ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE)
  • sub(pattern, replacement, x, ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE)
  • gsub(pattern, replacement, x, ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE)

Arguments

  • pattern:包含正则表达式的字符串;
  • x,text:寻找匹配的字符向量(或者可以被as.character强制转换为字符串的其他对象);
  • ignore.case:FALSE表示区分大小写,TRUE表示不区分;
  • perl:逻辑值,表示是否使用perl支持的字符表达式;
  • value:如果为假,则返回包含grep确定的匹配项的(整数)索引的向量;如果为真,则返回包含匹配元素本身的向量;
  • fixed:如果为真,pattern是要按原样匹配的字符串;
  • useBytes:如果为真,则按字节而不是按字符进行匹配;
  • invert:如果为真,则返回不匹配的元素的索引或值;
  • replacement:在sub和gsub中替换匹配的模式。对于fixed = FALSE,它可以包含对模式的括号子表达式的反向引用“\1”到“\9”。仅对于perl = TRUE,它还可以包含“\U”或“\L”来将替换的其余部分转换为大写或小写,“\E”转换为结束大小写转换。

Details

3种模式:

  1. fixed = TRUE:精确(普通)匹配;
  2. perl = TRUE:Perl正则匹配;
  3. fixed = FALSE, perl = FALSE:使用POSIX扩展正则匹配。

sub和gsub的不同仅在于替换第一个匹配项和所有匹配项。

对于regexpr、gregexpr和regexec,pattern如果为NA将会报错,否则NA是允许的,并给出一个NA匹配。

注意:R中转义需要用两个反斜杠\\。

Value

grep(value = FALSE)返回x元素的索引向量。

grep(value = TRUE)返回一个包含选定的x元素的字符向量。

grepl返回一个逻辑向量(对于x的每个元素是否匹配)。

regexpr返回一个与文本长度相同的整数向量,给出第一个匹配项的起始位置,如果没有匹配项,则返回-1,并带有一个整数向量“match.length”,给出匹配文本的长度(或-1表示没有匹配)。

gregexpr返回一个与文本长度相同的列表,其中每个元素的形式与regexpr的返回值相同,只是给出了每个匹配的起始位置。

regexec返回一个与文本长度相同的列表,如果没有匹配,则每个元素的长度为-1,或者返回一个整数序列,其中包含匹配的起始位置和与模式的圆括号子表达式对应的所有子字符串,并带有“match”属性。

sub和gsub返回与x相同长度和相同属性的字符向量。没有被替换的字符向量x的元素将不变地返回。

Examples

txt <- c("arm","foot","lefroo", "bafoobar")
grep("foo", txt)
[1] 2 4
Hide
grep("foo", txt, value = TRUE)
[1] "foot" "bafoobar"

## Double all 'a' or 'b's; "\" must be escaped, i.e., 'doubled'
gsub("([ab])", "\\1_\\1_", "abc and ABC")
[1] "a_a_b_b_c a_a_nd ABC"

txt <- c("The", "licenses", "for", "General")
regexpr("en", txt)
[1] -1 4 -1 2
attr(,"match.length")
[1] -1 2 -1 2
attr(,"index.type")
[1] "chars"
attr(,"useBytes")
[1] TRUE

## trim trailing white space
str <- "Now is the time "
sub(" +$", "", str) ## spaces only
[1] "Now is the time"
Hide

what is considered 'white space' depends on the locale.

sub("[[:space:]]+$", "", str) ## white space, POSIX-style
[1] "Now is the time"
Hide

what PCRE considered white space changed in version 8.34: see ?regex

sub("\\s+$", "", str, perl = TRUE) ## PCRE-style white space
[1] "Now is the time"

## capitalizing
txt <- "a test of capitalizing"
gsub("(\\w)(\\w*)", "\\U\\1\\L\\2", txt, perl=TRUE)
[1] "A Test Of Capitalizing"
Hide
gsub("\\b(\\w)", "\\U\\1", txt, perl=TRUE)
[1] "A Test Of Capitalizing"

## named capture
notables <- c(" Ben Franklin and Jefferson Davis",
"\tMillard Fillmore")

name groups 'first' and 'last'

name.rex <- "(?[[:upper:]][[:lower:]]+) (?[[:upper:]][[:lower:]]+)"
(parsed <- regexpr(name.rex, notables, perl = TRUE))
[1] 3 2
attr(,"match.length")
[1] 12 16
attr(,"index.type")
[1] "chars"
attr(,"useBytes")
[1] TRUE
attr(,"capture.start")
first last
[1,] 3 7
[2,] 2 10
attr(,"capture.length")
first last
[1,] 3 8
[2,] 7 8
attr(,"capture.names")
[1] "first" "last"
Hide
parse.one <- function(res, result) {
m <- do.call(rbind, lapply(seq_along(res), function(i) {
if(result[i] == -1) return("")
st <- attr(result, "capture.start")[i, ]
substring(res[i], st, st + attr(result, "capture.length")[i, ] - 1)
}))
colnames(m) <- attr(result, "capture.names")
m
}
parse.one(notables, parsed)
first last
[1,] "Ben" "Franklin"
[2,] "Millard" "Fillmore"

## Decompose a URL into its components.

Example by LT (http://www.cs.uiowa.edu/~luke/R/regexp.html).

x <- "http://stat.umn.edu:80/xyz"
m <- regexec("^(([^:]+)://)?([^:/]+)(:([0-9]+))?(/.*)", x)
m
[[1]]
[1] 1 1 1 8 20 21 23
attr(,"match.length")
[1] 26 7 4 12 3 2 4
attr(,"index.type")
[1] "chars"
attr(,"useBytes")
[1] TRUE
Hide
regmatches(x, m)
[[1]]
[1] "http://stat.umn.edu:80/xyz" "http://"
[3] "http" "stat.umn.edu"
[5] ":80" "80"
[7] "/xyz"

在R中没有找到合适的提取字符串中某一部分的函数,所以自己编写了一个如下。

比如,提取所有大写字母开头的单词。

SUB<-function(t,REG)
{
m<-gregexpr(REG, t)
start<-m[[1]]
stop<-start+attr(m[[1]],"match.length")-1
l<-length(start)
r<-rep("1",l)
for(i in 1:l)
{
r[i]<-substr(t,start[i],stop[i])
}
return(r)
}
temp<-c("I love Study",
"I have A CAT",
"there is a Blue Pen")
lapply(temp,SUB,REG="[A-Z][A-Za-z]*")