एक नियमित अभिव्यक्ति मैच निकालें


111

मैं एक स्ट्रिंग से एक नंबर निकालने की कोशिश कर रहा हूं।

और [0-9]+स्ट्रिंग पर कुछ ऐसा करें "aaa12xxx"और प्राप्त करें "12"

मैंने सोचा कि यह कुछ इस तरह होगा:

> grep("[0-9]+", "aaa12xxx", value=TRUE)
[1] "aaa12xxx"

और फिर मुझे लगा ...

> sub("[0-9]+", "\\1", "aaa12xxx")
[1] "aaaxxx"

लेकिन मुझे प्रतिक्रिया के कुछ रूप मिले:

> sub("[0-9]+", "ARGH!", "aaa12xxx")
[1] "aaaARGH!xxx"

एक छोटा सा विवरण मुझे याद आ रहा है।

जवाबों:


167

नए स्ट्रिंग पैकेज का उपयोग करें जो सभी मौजूदा नियमित अभिव्यक्ति को एक सुसंगत वाक्यविन्यास में संचालित करता है और कुछ ऐसे जोड़ देता है जो गायब हैं:

library(stringr)
str_locate("aaa12xxx", "[0-9]+")
#      start end
# [1,]     4   5
str_extract("aaa12xxx", "[0-9]+")
# [1] "12"

3
(लगभग) वास्तव में क्या मैं की जरूरत है, लेकिन जैसा कि मैंने में टाइपिंग शुरू कर दिया ?str_extractमैं देखा str_extract_allऔर जीवन अच्छा फिर से किया गया था।
dwanderson

94

' मानक कार्यों को अनदेखा करना ' - ' ?gsubविशेष रूप से देखें' में भी विशेष रूप से संदर्भ के लिए मदद फ़ाइल कहना शायद थोड़ा जल्दबाजी है :

'रेगेक्सप्र', 'ग्रीजएक्सप्रा' और 'रेगेक्सेक' के परिणामों के आधार पर मिलान किए गए सब्सट्रिंग निकालने के लिए 'रीजमैक्स'।

तो यह काम करेगा, और काफी सरल है:

txt <- "aaa12xxx"
regmatches(txt,regexpr("[0-9]+",txt))
#[1] "12"


15

आप PERL regexs के आलसी मिलान का उपयोग कर सकते हैं:

> sub(".*?([0-9]+).*", "\\1", "aaa12xx99",perl=TRUE)
[1] "12"

गैर-अंकों को स्थानापन्न करने की कोशिश करने से इस मामले में त्रुटि होगी।


4
अगर आपको थोड़ा बदसूरत इस्तेमाल करने की इच्छा हो, तो पेर को ज़रूरत नहीं है "[^ 0-9] * ([0-9] +)। *"
ज्योतिर्मय भट्टाचार्य

5

एक तरीका यह होगा:

test <- regexpr("[0-9]+","aaa12456xxx")

अब, नोटिस regexpr आपको स्ट्रिंग के शुरुआती और अंत सूचक देता है:

    > test
[1] 4
attr(,"match.length")
[1] 5

तो आप उस जानकारी को फंक्शन फ़ंक्शन के साथ उपयोग कर सकते हैं

substr("aaa12456xxx",test,test+attr(test,"match.length")-1)

मुझे यकीन है कि ऐसा करने का एक और अधिक सुंदर तरीका है, लेकिन यह सबसे तेज़ तरीका है जो मुझे मिल सकता है। वैकल्पिक रूप से, आप उप / gsub का उपयोग उस पट्टी को हटाने के लिए कर सकते हैं जिसे आप नहीं छोड़ना चाहते हैं।


5

प्रतिस्थापन में नियमित अभिव्यक्ति और समूह के संदर्भ में कोष्ठक कैप्चरिंग का उपयोग करें। कोष्ठकों में कुछ भी याद हो जाता है। फिर वे पहले आइटम \ 2 से एक्सेस करते हैं। पहला बैकस्लैश R में बैकस्लैश की व्याख्या से बच जाता है ताकि यह नियमित अभिव्यक्ति पार्सर को पास हो जाए।

gsub('([[:alpha:]]+)([0-9]+)([[:alpha:]]+)', '\\2', "aaa12xxx")

2

Gsubfn पैकेज में स्पष्ट रूप से उपयोग करना। स्ट्रेप्ली इस तरह लागू होते हैं कि आर्ग्स ऑब्जेक्ट, संशोधक और फ़ंक्शन होते हैं सिवाय इसके कि ऑब्जेक्ट स्ट्रिंग्स का एक वेक्टर है (एक सरणी के बजाय) और संशोधक एक नियमित अभिव्यक्ति है (एक मार्जिन के बजाय):

library(gsubfn)
x <- c("xy13", "ab 12 cd 34 xy")
strapply(x, "\\d+", as.numeric)
# list(13, c(12, 34))

यह x.numeric के माध्यम से प्रत्येक मैच पास करने वाले x के प्रत्येक घटक में एक या अधिक अंक (\ d +) से मेल करने के लिए कहता है। यह एक सूची देता है जिसके घटक x के संबंधित घटकों के मेल के वैक्टर हैं। आउटपुट को देखते हुए हम देखते हैं कि x के पहले घटक का एक मैच है जो १३ है और x के दूसरे घटक के दो मैच हैं जो १२ और ३४ हैं । अधिक जानकारी के लिए http://gsubfn.googlecode.com देखें ।


1

एक और समाधान:

temp = regexpr('\\d', "aaa12xxx");
substr("aaa12xxx", temp[1], temp[1]+attr(temp,"match.length")[1])

1

इनमें से एक महत्वपूर्ण अंतर किसी भी गैर-मैच के साथ व्यवहार का दृष्टिकोण है। उदाहरण के लिए, regmatches विधि इनपुट के समान लंबाई की एक स्ट्रिंग नहीं लौटा सकती है यदि सभी पदों में एक मेल नहीं है

> txt <- c("aaa12xxx","xyz")

> regmatches(txt,regexpr("[0-9]+",txt)) # could cause problems

[1] "12"

> gsub("[^0-9]", "", txt)

[1] "12" ""  

> str_extract(txt, "[0-9]+")

[1] "12" NA  

1

इस प्रश्न का हल

library(stringr)
str_extract_all("aaa12xxx", regex("[[:digit:]]{1,}"))
# [[1]]
# [1] "12"

[[: अंक:]] : अंक [0-9]

{},} : कम से कम 1 बार मेल खाता है


0

पैकेज का उपयोग करना unglue हम निम्नलिखित करना होगा:

# install.packages("unglue")
library(unglue)
unglue_vec(c("aaa12xxx", "aaaARGH!xxx"), "{prefix}{number=\\d+}{suffix}", var = "number")
#> [1] "12" NA

2019-11-06 को रेप्रेक्स पैकेज (v0.3.0) द्वारा बनाया गया

convertस्वचालित रूप से संख्या में परिवर्तित करने के लिए तर्क का उपयोग करें :

unglue_vec(
  c("aaa12xxx", "aaaARGH!xxx"), 
  "{prefix}{number=\\d+}{suffix}", 
  var = "number", 
  convert = TRUE)
#> [1] 12 NA

-2

आप C ++ के साथ अपने regex फ़ंक्शन लिख सकते हैं, उन्हें एक DLL में संकलित कर सकते हैं और उन्हें R से कॉल कर सकते हैं।

    #include <regex>

    extern "C" {
    __declspec(dllexport)
    void regex_match( const char **first, char **regexStr, int *_bool)
    {
        std::cmatch _cmatch;
        const char *last = *first + strlen(*first);
        std::regex rx(*regexStr);
        bool found = false;
        found = std::regex_match(*first,last,_cmatch, rx);
        *_bool = found;
    }

__declspec(dllexport)
void regex_search_results( const char **str, const char **regexStr, int *N, char **out )
{
    std::string s(*str);
    std::regex rgx(*regexStr);
    std::smatch m;

    int i=0;
    while(std::regex_search(s,m,rgx) && i < *N) {
        strcpy(out[i],m[0].str().c_str());
        i++;
        s = m.suffix().str();
    }
}
    };

आर के रूप में कॉल करें

dyn.load("C:\\YourPath\\RegTest.dll")
regex_match <- function(str,regstr) {
.C("regex_match",x=as.character(str),y=as.character(regstr),z=as.logical(1))$z }

regex_match("abc","a(b)c")

regex_search_results <- function(x,y,n) {
.C("regex_search_results",x=as.character(x),y=as.character(y),i=as.integer(n),z=character(n))$z }

regex_search_results("aaa12aa34xxx", "[0-9]+", 5)

4
यह पूरी तरह अनावश्यक है। आर। के अंदर एक आसान समाधान के लिए "thelatemail" या "रॉबर्ट" के उत्तर देखें
डैनियल हूप
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.