2009-06-04 9 views
67

आर में रेगेक्स समूह कैप्चर आर, क्या नियमित अभिव्यक्ति मिलान से समूह कैप्चर निकालना संभव है? जहां तक ​​मैं कह सकता हूं, grep, grepl, regexpr, gregexpr, sub, या gsub समूह कैप्चर को वापस लौटाएं।कई कैप्चर-ग्रुप

मैं तार से कुंजी-मान जोड़ों कि इस प्रकार इनकोड निकालने के लिए की जरूरत है:

\((.*?) :: (0\.[0-9]+)\) 

मैं हमेशा बस कई पूर्ण मैच greps कर सकते हैं, या कुछ बाहर (गैर आर) प्रसंस्करण करते हैं, लेकिन मैं उम्मीद कर रहा था कि मैं इसे आर के भीतर कर सकता हूं। क्या कोई ऐसा कार्य या पैकेज है जो ऐसा करने के लिए ऐसा कार्य प्रदान करता है?

उत्तर

88

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"  
+1

वास्तव में वास्तव में मुझे जो चाहिए था (वापस जब मैंने मूल रूप से सवाल पूछा था)। भावी संदर्भ के लिए स्वीकार्य के रूप में चिह्नित। धन्यवाद। –

+0

और 'str_match_all()' regex – smci

34

gsub इस करता है, अपने उदाहरण से:

gsub("\\((.*?) :: (0\\.[0-9]+)\\)","\\1 \\2", "(sometext :: 0.1231313213)") 
[1] "sometext 0.1231313213" 

आप उद्धरण तो वे regex के लिए काम में बच \ रों दोगुना करने की जरूरत है।

उम्मीद है कि इससे मदद मिलती है।

+0

वास्तव में मुझे डेटा.फ्रेम में कब्जा करने के लिए कब्जे वाले सबस्ट्रिंग को खींचने की आवश्यकता है। लेकिन, अपने उत्तर को देखते हुए, मुझे लगता है कि मैं जो चाहूं उसे प्राप्त करने के लिए चेन जीएसयूबी और कुछ स्ट्रस्प्लिट कर सकता हूं, शायद: strsplit (strsplit (gsub (regex, "\\ 1 :: \\ 2 ::::" , str), "::::") [[1]], "::") –

+5

ग्रेट। आर 'gsub' मैनपेज को बहुत बुरी तरह से एक उदाहरण की आवश्यकता है जिसमें आपको कैप्चर-ग्रुप संदर्भ से बचने के लिए' \\ 1 'की आवश्यकता है। एक कार्य कोड के लिए – smci

2

इस तरह मैं इस समस्या के आसपास काम करना समाप्त कर दिया। मैं पहले और दूसरे पर कब्जा समूहों से मेल खाती है और दो gregexpr कॉल चलाने के लिए, तो मिलान किया सबस्ट्रिंग बाहर निकलने के लिए दो अलग-अलग regexes प्रयोग किया है:)

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")) 
+0

+1। हालांकि, मैं आर से एक त्वरित खोल कमांड चलाऊंगा और इस 'expr "xyx0.0023xyxy":' [^ 0-9] * \ ([। 0-9] \ + \) जैसे बैश वन-लाइनर का उपयोग करूंगा। ' –

15

gsub (ऐसा करने के लिए और केवल कब्जा समूह लौट सकते हैं:

हालांकि, इसके लिए काम करने के लिए, आपको gsub() सहायता में उल्लिखित अपने कैप्चर समूह के बाहर स्पष्ट रूप से तत्वों का चयन करना होगा।

(...) चरित्र वैक्टर 'एक्स' के तत्व जिन्हें प्रतिस्थापित नहीं किया जाएगा उन्हें अपरिवर्तित वापस कर दिया जाएगा।

तो यदि आपका टेक्स्ट चुना जाना है तो कुछ स्ट्रिंग के बीच में स्थित है। * कैप्चर समूह से पहले और बाद में आपको इसे वापस करने की अनुमति देनी चाहिए।

gsub(".*\\((.*?) :: (0\\.[0-9]+)\\).*","\\1 \\2", "(sometext :: 0.1231313213)") [1] "sometext 0.1231313213"

16

regmatches() और regexec() का प्रयास करें:

regmatches("(sometext :: 0.1231313213)",regexec("\\((.*?) :: (0\\.[0-9]+)\\)","(sometext :: 0.1231313213)")) 
[[1]] 
[1] "(sometext :: 0.1231313213)" "sometext"     "0.1231313213" 
+1

में सभी समूहों से मेल खाने के लिए वेनिला आर समाधान के लिए धन्यवाद और 'regmatches' को इंगित करने के लिए धन्यवाद जो मैंने पहले कभी नहीं देखा है – Andy

3

मैं पर्ल संगत नियमित अभिव्यक्ति की तरह। शायद किसी और भी है ...

यहाँ एक समारोह है कि पर्ल संगत नियमित अभिव्यक्ति है कि मैं करने के लिए इस्तेमाल कर रहा हूँ अन्य भाषाओं में कार्यों की कार्यक्षमता से मेल खाता है और है: जैसा कि stringr पैकेज में सुझाव दिया

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 
} 
0

, यह 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" 
0

से strcapture के साथ समाधान:

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