2015-11-22 13 views
6

से शब्दों को निकालने का अनुमान है, मुझे लगता है कि यह एक आम समस्या है, और मुझे SO से कुछ सहित कई वेबपृष्ठ मिले, लेकिन मैं इसे समझने में असफल रहा।आर में REGEX: स्ट्रिंग

मैं रेगेक्स के लिए नया हूं, और मैं इसे वाक्य में पहले कुछ शब्दों को निकालने के लिए आर में उपयोग करना चाहता हूं।

उदाहरण के लिए, अगर मेरे वाक्य

z = "I love stack overflow it is such a cool site" 

आईडी होने के रूप में मेरी उत्पादन के लिए (अगर मैं पहले चार शब्द की जरूरत है) की तरह

[1] "I love stack overflow" 

या (अगर मैं पिछले चार की जरूरत है शब्द)

[1] "such a cool site" 
निश्चित रूप से

, निम्न कार्य करता

paste(strsplit(z," ")[[1]][1:4],collapse=" ") 
paste(strsplit(z," ")[[1]][7:10],collapse=" ") 

लेकिन मैं प्रदर्शन के मुद्दों के लिए एक regex समाधान की कोशिश करना चाहते हैं के रूप में मैं बहुत बड़ा फाइलों के साथ सौदा करने की जरूरत है (और यह भी इसके बारे में जानने के लिए)

मैं कई लिंक को देखा, सहित Regex to extract first 3 words from a string और http://osherove.com/blog/2005/1/7/using-regex-to-return-the-first-n-words-in-a-string.html

तो मैं

gsub("^((?:\S+\s+){2}\S+).*",z,perl=TRUE) 
Error: '\S' is an unrecognized escape in character string starting ""^((?:\S" 

मैं अन्य सामान की कोशिश की लेकिन यह आम तौर पर मुझे या तो पूरी स्ट्रिंग लौटे तरह बातें करने की कोशिश की , या खाली स्ट्रिंग।

सबस्ट्र के साथ एक और समस्या यह है कि यह एक सूची देता है। शायद ऐसा लगता है कि [[]] ऑपरेटर बड़ी फ़ाइलों से निपटने और लागू सामग्री करने पर चीजों को धीमा कर रहा है (??)।

ऐसा लगता है कि आर में इस्तेमाल सिंटेक्स कुछ अलग है? धन्यवाद!

+2

आपको आर रेगेक्स में डबल एस्केप का उपयोग करने की आवश्यकता है। '\ S' ->' \\ एस' –

+0

आप 'stringi :: stri_extract_all_words (z) [[1]] [1: 4]' का उपयोग भी कर सकते हैं, जिसका उपयोग करना आसान है और रेगेक्स को जानने की आवश्यकता नहीं है। हालांकि आप शब्दों को एक अलग मूल्य प्राप्त करेंगे। –

+0

क्या आप उसी विचार का उपयोग नहीं कर सकते जिसे मैंने साझा किया था [आपके पिछले प्रश्न में] (http://stackoverflow.com/questions/33785594/manipulate-char-vectors-inside-a-data-table-object-in -r)? आपको केवल आर में अपनी बैकस्लैश पर दोगुनी करने की आवश्यकता है, जैसा कि पहले से ही @stribizhev द्वारा इंगित किया गया है। – A5C1D2H2I1M1N2O1R2T1

उत्तर

5

आप पहले से ही एक जवाब स्वीकार कर लिया है, लेकिन मैं आपको आर में regex के बारे में थोड़ा और अधिक समझ की मदद करने का एक साधन के रूप में इस साझा करने के लिए जा रहा हूँ, जब से तुम वास्तव में बहुत पर जवाब हो रही के करीब थे अपने खुद।

  1. आप एकल बैकस्लैश (\) का इस्तेमाल किया:


    अपने gsub दृष्टिकोण के साथ दो समस्याएं हैं। आर के लिए आपको उनसे बचने की आवश्यकता है क्योंकि वे विशेष पात्र हैं। आप एक और बैकस्लैश (\\) जोड़कर उनसे बचें। यदि आप nchar("\\") करते हैं, तो आप देखेंगे कि यह "1" देता है।

  2. आपने यह निर्दिष्ट नहीं किया कि प्रतिस्थापन क्या होना चाहिए। यहां, हम कुछ भी प्रतिस्थापित नहीं करना चाहते हैं, लेकिन हम स्ट्रिंग का एक विशिष्ट भाग कैप्चर करना चाहते हैं।आप समूह को (...) पर कैप्चर करते हैं, और फिर आप उन्हें समूह की संख्या से संदर्भित कर सकते हैं। यहां, हमारे पास सिर्फ एक समूह है, इसलिए हम इसे "\\1" के रूप में संदर्भित करते हैं। "Z" की सामग्री के शुरू से ही

    • कार्य:

      sub("^((?:\\S+\\s+){2}\\S+).*", "\\1", z, perl = TRUE) 
      # [1] "I love stack" 
      

      यह अनिवार्य रूप से कह रहा है:

आप की तरह कुछ करने की कोशिश की जानी चाहिए थी।

  • बनाने प्रारंभ समूह 1.
  • (\S+\s+) दो बार {2} खाली स्थान के द्वारा पीछा में गैर-सफ़ेद (एक शब्द की तरह) और फिर गैर व्हाइटस्पेस के अगले सेट (\S+) का पता लगाएं। यह हमें तीसरे शब्द के बाद व्हाइटस्पेस प्राप्त किए बिना 3 शब्द प्राप्त करेगा। इस प्रकार, यदि आप शब्दों की एक अलग संख्या चाहते थे, तो {2} को उस संख्या से कम होने के लिए बदलें जो वास्तव में आपके बाद है।
  • अंतिम समूह 1 वहां।
  • फिर, "z" से समूह 1 (\1) की सामग्री वापस करें।

  • पिछले तीन शब्दों के लिए, बस कैप्चरिंग समूह की स्थिति को स्विच और पैटर्न से मेल करने के अंत में डाल दिया।

    sub("^.*\\s+((?:\\S+\\s+){2}\\S+)$", "\\1", z, perl = TRUE) 
    # [1] "a cool site" 
    
    +0

    धन्यवाद। @ अन्नदा महतो। क्या आप उसी कार्य 'उप' का उपयोग कर पिछले 4 शब्दों के लिए रेगेक्स दे सकते हैं? –

    +1

    @ फ़ैगुई कर्टैन, मैंने संदर्भ को अंत में लाइन की शुरुआत में तय करने के बजाय संदर्भित किया है, जैसे: '^। * ((?: \\ S + \\ s +) {2} \\ S +) $'। 3 के बजाय 4 शब्द प्राप्त करने के लिए "2" से "3" बदलें। – A5C1D2H2I1M1N2O1R2T1

    3

    पहले चार शब्द प्राप्त करने के लिए।

    library(stringr) 
    str_extract(x, "^\\s*(?:\\S+\\s+){3}\\S+") 
    

    अंतिम चार प्राप्त करने के लिए।

    str_extract(x, "(?:\\S+\\s+){3}\\S+(?=\\s*$)") 
    
    +0

    या 'sub ("^\\ s * ((?: \\ S + \\ s +) {3} \\ S +) की आवश्यकता है। । * "," \\ 1 ", x)' –

    +0

    क्या आप मुझे 'उप'' फ़ंक्शन का उपयोग करके सही रेगेक्स दे सकते हैं। मैंने 10,000 नमूने पर एक परीक्षण किया और बेस आर से 'उप' फ़ंक्शन 'लाइब्रेरी (स्ट्रिंग)' से 'str_extract' की तुलना में 30 गुना तेज है। धन्यवाद –

    +0

    मैं बेवकूफ हूं लेकिन फ़ंक्शन को ट्विक करने के बारे में नहीं जानता। 'सब (" (?: \\ एस + \\ एस +) {3} \\ एस + (? = \\ एस * $) ", प्रतिस्थापन =" ", जेड, perl = TRUE) 'मुझे वापस कर रहा है' 'मुझे प्यार है स्टैक ओवरफ़्लो यह है "'जो सब कुछ है लेकिन पिछले 4 शब्द ... –

    संबंधित मुद्दे