假设我有一个像"ABC(123-456-789)"的字符串,我想知道从中检索"123-456-789"的最佳方法是什么.
strsplit("A B C (123-456-789)", "\\(")
[[1]]
[1] "A B C" "123-456-789)"
Run Code Online (Sandbox Code Playgroud)
如果我们想要-在大括号之间提取数字,则有一个选项str_extract.如果字符串中有多个模式,请使用str_extract_all
library(stringr)
str_extract(str1, '(?<=\\()[0-9-]+(?=\\))')
#[1] "123-456-789"
str_extract_all(str2, '(?<=\\()[0-9-]+(?=\\))')
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我们使用正则表达式的外观来提取数字和-.积极的lookbehind (?<=\\()[0-9-]+匹配数字和-([0-9-]+)in (123-456-789而不是123-456-789.类似地,先行( '[0-9 - ] +(= \)?')沿着相匹配号码-中123-456-789)而不是在123-456-798.总之,它匹配满足这两个条件的所有情况,(123-456-789)并在外观之间提取它们,而不是像(123-456-789或等情况123-456-789)
随着strsplit您可以指定split为[()].我们将()方括号内部保留[]为将其视为字符,否则我们必须转义括号('\\(|\\)').
strsplit(str1, '[()]')[[1]][2]
#[1] "123-456-789"
Run Code Online (Sandbox Code Playgroud)
如果有多个子字符串要从字符串中提取,我们可以循环使用lapply并提取数字拆分部分grep
lapply(strsplit(str2, '[()]'), function(x) grep('\\d', x, value=TRUE))
Run Code Online (Sandbox Code Playgroud)
或者我们也可以使用stri_split从中stringi删除空字符串的选项(omit_empty=TRUE).
library(stringi)
stri_split_regex(str1, '[()A-Z ]', omit_empty=TRUE)[[1]]
#[1] "123-456-789"
stri_split_regex(str2, '[()A-Z ]', omit_empty=TRUE)
Run Code Online (Sandbox Code Playgroud)
另一个选择是rm_round,qdapRegex如果我们有兴趣提取括号内的内容.
library(qdapRegex)
rm_round(str1, extract=TRUE)[[1]]
#[1] "123-456-789"
rm_round(str2, extract=TRUE)
Run Code Online (Sandbox Code Playgroud)
str1 <- "A B C (123-456-789)"
str2 <- c("A B C (123-425-478) A", "ABC(123-423-428)",
"(123-423-498) ABCDD",
"(123-432-423)", "ABC (123-423-389) GR (124-233-848) AK")
Run Code Online (Sandbox Code Playgroud)
或者sub来自base R:
sub("[^(]+\\(([^)]+)\\).*", "\\1", "A B C (123-456-789)")
#[1] "123-456-789"
Run Code Online (Sandbox Code Playgroud)
说明:
[^(]+:匹配除开始括号之外的任何内容
\\(:匹配一个左括号的开始括号:匹配
([^)]+)您想要捕获的模式(然后将其检索到replacement="\\1"),除了结束括号之外的任何内容都
\\).*匹配后面的括号,0次或更多次
另一种选择,具有前瞻和后视功能
sub(".*(?<=\\()(.+)(?=\\)).*", "\\1", "A B C (123-456-789)", perl=TRUE)
#[1] "123-456-789"
Run Code Online (Sandbox Code Playgroud)
捕获组sub将定位您想要的输出:
sub('.*\\((.*)\\).*', '\\1', str1)
[1] "123-456-789"
Run Code Online (Sandbox Code Playgroud)
额外检查以确保我通过@ akrun的扩展示例:
sub('.*\\((.*)\\).*', '\\1', str2)
[1] "123-425-478" "123-423-428" "123-423-498" "123-432-423" "124-233-848"
Run Code Online (Sandbox Code Playgroud)