在R中,是否可以從正則表達式匹配中提取組捕獲?據我所知,沒有grep
,grepl
,regexpr
,gregexpr
,sub
或gsub
返回組捕獲。R中的正則表達式組捕獲多個捕獲組
我需要提取從字符串鍵 - 值對被這樣編碼:
\((.*?) :: (0\.[0-9]+)\)
我總是可以只是做多個全匹配裏grep,或做一些外(非-R)的處理,但我希望我可以在R內完成所有工作。是否有一個函數或一個包提供了這樣的功能?
在R中,是否可以從正則表達式匹配中提取組捕獲?據我所知,沒有grep
,grepl
,regexpr
,gregexpr
,sub
或gsub
返回組捕獲。R中的正則表達式組捕獲多個捕獲組
我需要提取從字符串鍵 - 值對被這樣編碼:
\((.*?) :: (0\.[0-9]+)\)
我總是可以只是做多個全匹配裏grep,或做一些外(非-R)的處理,但我希望我可以在R內完成所有工作。是否有一個函數或一個包提供了這樣的功能?
str_match()
,從stringr
包,將做到這一點。它返回一個字符矩陣的比賽中爲每個組一列(一個用於整場比賽):
> s = c("(sometext :: 0.1231313213)", "(moretext :: 0.111222)")
> str_match(s, "\\((.*?) :: (0\\.[0-9]+)\\)")
[,1] [,2] [,3]
[1,] "(sometext :: 0.1231313213)" "sometext" "0.1231313213"
[2,] "(moretext :: 0.111222)" "moretext" "0.111222"
GSUB做到這一點,從您的例子:
gsub("\\((.*?) :: (0\\.[0-9]+)\\)","\\1 \\2", "(sometext :: 0.1231313213)")
[1] "sometext 0.1231313213"
你需要加倍引號然後他們對正則表達式的工作逃脫\ S。
希望這會有所幫助。
其實我需要把捕獲的子串放到data.frame中。但是,看看你的答案,我想我可以鏈接gsub和幾個strsplit來得到我想要的,也許: strsplit(strsplit(gsub(正則表達式,「\\ 1 :: \\ 2 ::::」 ,str),「::::」)[[1]],「::」) – 2009-06-05 16:03:18
太好了。 R`gsub`手冊頁非常需要一個示例,顯示您需要'\\ 1'來轉義捕獲組引用。 – smci 2014-03-26 15:51:45
這就是我最終解決這個問題的方法。我用了兩個獨立的正則表達式匹配的第一和第二捕捉組和運行兩個gregexpr
電話,然後拉出匹配的字符串:
regex.string <- "(?<=\\().*?(?= ::)"
regex.number <- "(?<= ::)\\d\\.\\d+"
match.string <- gregexpr(regex.string, str, perl=T)[[1]]
match.number <- gregexpr(regex.number, str, perl=T)[[1]]
strings <- mapply(function (start, len) substr(str, start, start+len-1),
match.string,
attr(match.string, "match.length"))
numbers <- mapply(function (start, len) as.numeric(substr(str, start, start+len-1)),
match.number,
attr(match.number, "match.length"))
對於工作代碼+1。但是,我寧願從R運行一個快速shell命令,並使用像這樣的`expr「xyx0.0023xyxy」:'[^ 0-9] * \([。0-9] \ + \) '' – 2011-09-01 23:18:27
GSUB()可以做到這一點,只返回捕獲組:
但是,爲了使其發揮作用,您必須按照gsub()幫助中的說明明確選擇捕獲組外部的元素。
(...)未被替換的字符向量'x'的元素將不會被返回。
因此,如果您要選擇的文本位於某個字符串的中間,那麼在捕獲組之前和之後添加。*應允許您只返回它。
gsub(".*\\((.*?) :: (0\\.[0-9]+)\\).*","\\1 \\2", "(sometext :: 0.1231313213)") [1] "sometext 0.1231313213"
嘗試regmatches()
和regexec()
:
regmatches("(sometext :: 0.1231313213)",regexec("\\((.*?) :: (0\\.[0-9]+)\\)","(sometext :: 0.1231313213)"))
[[1]]
[1] "(sometext :: 0.1231313213)" "sometext" "0.1231313213"
我喜歡Perl兼容的正則表達式。也許別人不會太...
這裏是做Perl兼容的正則表達式和匹配,我用其他語言的函數功能的函數:
regexpr_perl <- function(expr, str) {
match <- regexpr(expr, str, perl=T)
matches <- character(0)
if (attr(match, 'match.length') >= 0) {
capture_start <- attr(match, 'capture.start')
capture_length <- attr(match, 'capture.length')
total_matches <- 1 + length(capture_start)
matches <- character(total_matches)
matches[1] <- substr(str, match, match + attr(match, 'match.length') - 1)
if (length(capture_start) > 1) {
for (i in 1:length(capture_start)) {
matches[i + 1] <- substr(str, capture_start[[i]], capture_start[[i]] + capture_length[[i]] - 1)
}
}
}
matches
}
正如stringr
包建議這可以使用str_match()
或str_extract()
來實現。
library(stringr)
strings <- c(" 219 733 8965", "329-293-8753 ", "banana",
"239 923 8115 and 842 566 4692",
"Work: 579-499-7527", "$1000",
"Home: 543.355.3679")
phone <- "([2-9][0-9]{2})[- .]([0-9]{3})[- .]([0-9]{4})"
提取和我們的團體組合:
str_extract(strings, phone)
# [1] "219 733 8965" "329-293-8753" NA "239 923 8115" "579-499-7527" NA
# [7] "543.355.3679"
指示組,輸出矩陣(我們感興趣的列2+):
從手動改編
str_match(strings, phone)
# [,1] [,2] [,3] [,4]
# [1,] "219 733 8965" "219" "733" "8965"
# [2,] "329-293-8753" "329" "293" "8753"
# [3,] NA NA NA NA
# [4,] "239 923 8115" "239" "923" "8115"
# [5,] "579-499-7527" "579" "499" "7527"
# [6,] NA NA NA NA
# [7,] "543.355.3679" "543" "355" "3679"
與strcapture
解決方案從utils
:
x <- c("key1 :: 0.01",
"key2 :: 0.02")
strcapture(pattern = "(.*) :: (0\\.[0-9]+)",
x = x,
proto = list(key = character(), value = double()))
#> key value
#> 1 key1 0.01
#> 2 key2 0.02
這實際上正是我所需要的(當我最初問這個問題時)。標記爲未來參考。謝謝。 – 2012-04-06 20:35:20