假设我有一个字符串,例如 "A B C (123-456-789)",我想知道从中获取 "123-456-789" 的最佳方法是什么。
strsplit("A B C (123-456-789)", "\\(")
[[1]]
[1] "A B C" "123-456-789)"
如果我们想要提取括号内带有-
的数字,一个选项是使用str_extract
。如果字符串中有多个模式,请使用str_extract_all
library(stringr)
str_extract(str1, '(?<=\\()[0-9-]+(?=\\))')
#[1] "123-456-789"
str_extract_all(str2, '(?<=\\()[0-9-]+(?=\\))')
在上述代码中,我们使用正则表达式环视来提取数字和-
。 正向后瞻(?<=\\()[0-9-]+
匹配数字以及-
([0-9-]+
) 在 (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"
如果需要从一个字符串中提取多个子字符串,我们可以使用 lapply
循环,并使用 grep
提取数值分裂的部分。
lapply(strsplit(str2, '[()]'), function(x) grep('\\d', x, value=TRUE))
或者我们可以使用来自 stringi
的 stri_split
,它具有删除空字符串的选项(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)
如果我们想要提取括号内的内容,那么另一个选择是来自qdapRegex
的rm_round
。
library(qdapRegex)
rm_round(str1, extract=TRUE)[[1]]
#[1] "123-456-789"
rm_round(str2, extract=TRUE)
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")
sub
函数:sub("[^(]+\\(([^)]+)\\).*", "\\1", "A B C (123-456-789)")
#[1] "123-456-789"
解释:
[^(]+
:匹配除开括号的任何字符
\\(
:匹配你想要的内容之前的左括号
([^)]+)
:匹配你想捕获的模式(然后在 replacement="\\1"
中检索),它是除了右括号之外的任何字符
\\).*
:匹配右括号后面的任何内容,0 次或多次
另一种选项:使用向前和向后查找
sub(".*(?<=\\()(.+)(?=\\)).*", "\\1", "A B C (123-456-789)", perl=TRUE)
#[1] "123-456-789"
sub
中的捕获组将定位到您所需的输出:sub('.*\\((.*)\\).*', '\\1', str1)
[1] "123-456-789"
额外的检查,以确保我通过@akrun的扩展示例:
sub('.*\\((.*)\\).*', '\\1', str2)
[1] "123-425-478" "123-423-428" "123-423-498" "123-432-423" "124-233-848"
也可以尝试这个:
k<-"A B C (123-456-789)"
regmatches(k,gregexpr("*.(\\d+).*",k))[[1]]
[1] "(123-456-789)"
在@Arun的建议下:
regmatches(k, gregexpr('(?<=\\()[^A-Z ]+(?=\\))', k, perl=TRUE))[[1]]
在@akrun的建议下:
regmatches(k, gregexpr('[0-9-]+', k))[[1]]
> gsub("[^\\d-]", "", x, perl=T)
[1] "123-456-789"
> gsub(".*\\(|\\)", "", x)
[1] "123-456-789"
> gsub("[^0-9-]", "", x)
[1] "123-456-789"
Few more...
> gsub("[0-9-](*SKIP)(*F)|.", "", x, perl=T)
[1] "123-456-789"
> gsub("(?:(?![0-9-]).)*", "", x, perl=T)
[1] "123-456-789"
strsplit(str1, '[()]')[[1]][2]
,但前提是需要事先知道位置。 - akrunstrsplit("A B C (123-456-789)", "\\(|\\)")[[1]][2]
的意思是:将字符串"A B C (123-456-789)"按照括号进行拆分,并返回第一个子字符串再按空格划分后的第二个元素。 - zx8754