2010-01-29 14 views
11

मेरे इनपुट में उपयोगकर्ता द्वारा पोस्ट किए गए स्ट्रिंग शामिल हैं।रेगेक्स: स्ट्रिंग से शब्द कैसे प्राप्त करें (सी #)

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

उदाहरण के लिए, इनपुट "#@[email protected] YOU'VE BEEN \***PWN3D*** ! :') !!!1einszwei drei !"

उत्पादन की आवश्यकता सूची है:

  • "LOLOLOL"
  • "YOU'VE"
  • "BEEN"
  • "PWN3D"
  • "einszwei"
  • "drei"

मैं नियमित अभिव्यक्ति में कोई नायक हूँ और Googling गया है, लेकिन मेरे गूगल-कुंगफू तेजी कमजोर है & hellip है;

मैं इनपुट से वांछित आउटपुट में कैसे जाउंगा?

+3

http://regular-expressions.info – Jason

उत्तर

18

सरल Regex:

\w+

यह "शब्द" वर्णों की स्ट्रिंग से मेल खाता है। यह लगभग है जो आप चाहते हैं।

यह थोड़ा अधिक सटीक है:

\w(?<!\d)[\w'-]*

यह शब्द है वर्णों की संख्या से मेल खाता है, यह सुनिश्चित करना कि पहला वर्ण कोई अंकों नहीं था।

यहाँ मेरी मैचों हैं:

1 Lololol
2 आपने
3 किया गया
4 PWN3D
5 einszwei
6 Drei

अब, यह अधिक की तरह है यह।

संपादित करें:
नकारात्मक-पीछे देखने के लिए कारण यह है कि कुछ regex जायके यूनिकोड वर्णों का समर्थन करते है। [ए-जेए-जेड] का उपयोग करना वांछनीय कुछ "शब्द" वर्णों को याद करेगा। \w को अनुमति देने और \d को अस्वीकार करने वाले सभी यूनिकोड वर्ण शामिल हैं जो पाठ के किसी भी ब्लॉक में एक शब्द को कल्पनापूर्वक शुरू करेंगे।

संपादित करें 2: एक ही नकारात्मक बहिष्कार के साथ डबल नकारात्मक चरित्र वर्ग:
मैं नकारात्मक lookbehind का असर पाने के लिए एक और अधिक संक्षिप्त तरीके से मिल गया है।

[^\W\d][\w'-]*(?<=\w)

यह अपवाद यह भी सुनिश्चित करता है कि उस शब्द समाप्त होता है एक शब्द भी चरित्र के साथ के साथ ऊपर के समान है। और अंत में, वहाँ है:

[^\W\d](\w|[-']{1,2}(?=\w))*

सुनिश्चित करना है कि वहाँ एक पंक्ति में दो से अधिक गैर-शब्द-वर्ण हैं। उर्फ, यह "शब्द-अप" से मेल खाता है लेकिन "शब्द-अप" नहीं, जो समझ में आता है। यदि आप इसे "वर्ड-अप" से मेल करना चाहते हैं, लेकिन "शब्द --- ऊपर" नहीं, तो आप 2 को 3 पर बदल सकते हैं।

+0

आपको बहुत धन्यवाद, एक आकर्षण की तरह काम करता है! :) – Led

+0

@ लेड: आप संपादन # 2 के अंत में रेगेक्स को देखना चाह सकते हैं। यह आप जो खोज रहे हैं उसके करीब हो सकता है। –

+0

डाउनवॉटेड। 'प्रतीक' वाले शब्द –

5

आपको प्राकृतिक भाषा प्रसंस्करण (एनएलपी) में देखना चाहिए, नियमित रूप से अभिव्यक्ति नहीं, और यदि आप एक से अधिक बोली जाने वाली भाषा को लक्षित कर रहे हैं, तो आपको भी इसमें कारक करने की आवश्यकता है। चूंकि आप सी # का उपयोग कर रहे हैं, SharpNLP प्रोजेक्ट देखें।

संपादित करें: यह दृष्टिकोण केवल तभी जरूरी है जब आप उन शब्दों की अर्थपूर्ण सामग्री की परवाह करते हैं जिन्हें आप विभाजित करने की कोशिश कर रहे हैं।

+1

धन्यवाद प्रतिक्रिया के लिए बहुत कुछ!:) लेकिन इसे सरल रखें और कहें कि मुझे भाषा की परवाह नहीं है - - मैं केवल वैकल्पिक रूप से '' 'और/या' - 'चरित्र वाले शब्दों पर विचार करूंगा? – Led

+1

@ माइक एटलस, अच्छा लिंक। +1 – Gabe

+0

यदि आपको भाषा की परवाह नहीं है, तो केवल स्ट्रिंग क्यों न करें। उन सभी पात्रों को बदलें() जिन्हें आप नहीं चाहते हैं और फिर स्ट्रिंग करें। इसे स्पेस कैरेक्टर पर टाइप करें? नियमित अभिव्यक्तियों की कोई ज़रूरत नहीं है। –

2

यदि आपको टोकनिंग करना है तो आप इसके लिए एक रेगेक्स की आवश्यकता नहीं है। सबसे पहले आप रिक्त स्थान को छोड़कर सभी गैर-अक्षर वर्णों को हटाकर स्ट्रिंग को sanitize कर सकते हैं और फिर स्पेस कैरेक्टर पर Split() करें। यह ज्यादातर सब कुछ के लिए काम करेगा, हालांकि संकुचन मुश्किल हो सकता है। आपको कम से कम शुरू करना चाहिए।

+0

ठीक है, तो मैं जो करना चाहता हूं वह सभी अमान्य वर्णों को हटा देता है, लेकिन 'और - वर्ण भी अमान्य हैं अगर वे वर्णमाला वर्णों के बीच में नहीं हैं। ("वर्ड-अप" में - मान्य है, "शब्द ----- ऊपर" में - वर्ण हटा दिए जाने चाहिए ...) – Led

+0

आप वहां एक चेक डाल सकते हैं जो यह देखने के लिए देखेगा कि '' ' या '-' अक्षर वर्णों से घिरा हुआ है और यदि वे हैं, तो हटाएं नहीं। – Jason

0

मेरा आंत महसूस नियमित अभिव्यक्तियों का उपयोग नहीं करेगा, लेकिन केवल एक लूप या दो करें। एक वैध चार स्ट्रिंग में प्रत्येक चार से अधिक

दोहराएं, अगर नहीं, एक अंतरिक्ष फिर String.Split का उपयोग() और विभाजन रिक्त स्थान के ऊपर से बदल दें।

एपॉस्ट्रोफिस और हाइफ़न यह निर्धारित करने के लिए थोड़ा और मुश्किल हो सकता है कि वे जंक कैरेक्टर या लीजेट वाले हैं या नहीं। लेकिन यदि आप स्ट्रिंग पर फिर से चलने के लिए लूप का उपयोग कर रहे हैं तो वर्तमान चरित्र से पीछे और आगे की तरफ देखकर आपकी मदद करनी चाहिए।

फिर आपके पास शब्दों की एक सूची होगी - इन शब्दों में से प्रत्येक के लिए जांच करें कि क्या वे आपके शब्दकोश में मान्य हैं या नहीं। यदि आप इसे तेजी से करना चाहते हैं, तो बाइनरी खोज का कुछ भाग्य प्रदर्शन करना सबसे अच्छा होगा। लेकिन इसे एक रैखिक खोज करने के लिए बस शुरू करना आसान होगा।

संपादित करें: मैंने केवल शब्दकोष की बात की है क्योंकि मैंने सोचा था कि आपको केवल वैध शब्दों में रुचि हो सकती है, यानी "asdfasdf" नहीं, लेकिन आखिरी कथन को अनदेखा करें यदि आपको इसकी आवश्यकता नहीं है।

+0

आप अमान्य वर्ण w/spaces को प्रतिस्थापित नहीं करना चाहते हैं। – Jason

2

निम्नलिखित

var pattern = new Regex(
    @"([^\W_\d]    # starting with a letter 
          # followed by a run of either... 
     ([^\W_\d] |   # more letters or 
     [-'\d](?=[^\W_\d]) # ', -, or digit followed by a letter 
    )* 
     [^\W_\d]    # and finishing with a letter 
    )", 
    RegexOptions.IgnorePatternWhitespace); 

var input = "#@[email protected] YOU'VE BEEN *PWN3D* ! :') !!!1einszwei drei foo--bar!"; 

foreach (Match m in pattern.Matches(input)) 
    Console.WriteLine("[{0}]", m.Groups[1].Value); 

का उपयोग करते हुए पैदा करता

[LOLOLOL] 
[YOU'VE] 
[BEEN] 
[PWN3D] 
[einszwei] 
[drei] 
[foo] 
[bar]
+0

भागों में विभाजित हैं, क्या आप सामान्य रूप से रेगेक्स लिख सकते हैं? मेरा मतलब है अतिरिक्त पात्रों के बिना सिंगल लाइन –

+0

अच्छी व्याख्या। – AnthonyVO

0

के उत्पादन में मैं इस तरह स्ट्रिंग के लिए एक एक्सटेंशन लिखा है:

private static string[] GetWords(string text) 
    { 
     List<string> lstreturn = new List<string>(); 
     List<string> lst = text.Split(new[] { ' ' }).ToList(); 
     foreach (string str in lst) 
     { 
      if (str.Trim() == "") 
      { 
       lstreturn.Add(str); 
      } 
     } 
     return lstreturn.ToArray(); 
    } 
+0

यह मेरे लिए एक विस्तार की तरह प्रतीत नहीं होता है। क्या आप 'यह' गायब हैं? –

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