2010-09-14 13 views
13

मुझे लगता है मैं इस तरह अनदेखा करना चाहते शब्दों की एक सूची है का उपयोग कर की जगह:स्ट्रिंग एक सूची <string>

public List<String> ignoreList = new List<String>() 
     { 
      "North", 
      "South", 
      "East", 
      "West" 
     }; 

एक दिया स्ट्रिंग के लिए, "14th Avenue North" कहते हैं कि मैं "उत्तर" भाग को दूर करने में सक्षम होना चाहते, इसलिए मूल रूप से एक फ़ंक्शन जो "14th Avenue " को कॉल करने पर वापस आ जाएगा।

मुझे लगता है कि मुझे LINQ, regex और प्रतिस्थापन के मिश्रण के साथ कुछ करने में सक्षम होना चाहिए, लेकिन मैं इसे समझ नहीं सकता।

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

+1

लेकिन यह एक पंक्ति @ एचटीडब्ल्यू नहीं है। यदि कोई एक पंक्ति नहीं है तो आपको कोई गीक पॉइंट नहीं मिलता है। –

+8

इस कार्यक्रम को शार्लोट, एनसी में चलाने दें मत। प्रमुख सड़क के नाम पूर्वी Blvd, दक्षिण Blvd, पश्चिम Blvd होने के लिए होता है। वे सड़कों के नाम हैं, * अब आप पश्चिम 1 स्ट्रीट पर नहीं हैं। * उस नोट पर, अन्य परिदृश्य भी हैं जहां आपकी दिशाएं वास्तव में दिशा-निर्देश नहीं हैं, लेकिन पहचानकर्ता के प्रमुख भाग हैं। नॉर्थम्प्टन, नॉर्थलेक (चार्लोट में मॉल/क्षेत्र), उत्तरी कैरोलिना, उत्तरी डकोटा, आदि –

+0

@ एंथनी: यह सच है, मैं अपने शब्दकोश में जो कुछ भी डालता हूं उससे सावधान रहूंगा। हालांकि, मैं डाक कोड (ज़िप) से पहले मेल खाता हूं जो कि फ़ंक्शन के लिए सटीक रूप से मेल खाने के लिए मेल खाना चाहिए। वहां से, मुझे वास्तव में कोई फर्क नहीं पड़ता कि अगर मैं नतीजों को याद करने के लिए झूठी सकारात्मकता प्राप्त करता हूं। –

उत्तर

12

इस बारे में कैसे:

string.Join(" ", text.Split().Where(w => !ignoreList.Contains(w))); 

या नेट 3 के लिए:

string.Join(" ", text.Split().Where(w => !ignoreList.Contains(w)).ToArray()); 

नोट है कि इस विधि अलग-अलग शब्दों में स्ट्रिंग विभाजन तो यह केवल संपूर्ण शब्दों को निकाल देता है। इस तरह यह Northampton Way #123 जैसे पते के साथ ठीक से काम करेगा कि string.Replace संभाल नहीं सकता है।

+0

* एसआईपी * - पर्ल की तरह स्वाद! –

+0

यह रेगेक्स संस्करणों की तुलना में कम और स्पष्ट दोनों का एक अच्छा समाधान है। – AHM

+0

आप शब्दों के साथ-साथ विभाजित भी हो सकते हैं - 'text.Split (ignoreList.ToArray(), StringSplitOptions.None) '। उस ने कहा, मामले को अनदेखा करने के लिए अपने दृष्टिकोण को अनुकूलित करना आसान है। – Kobi

2

कुछ इस तरह काम करना चाहिए:

string FilterAllValuesFromIgnoreList(string someStringToFilter) 
{ 
    return ignoreList.Aggregate(someStringToFilter, (str, filter)=>str.Replace(filter, "")); 
} 
+1

मुझे संदेह है कि यह सही है, और फिर भी मुझे वास्तव में पता नहीं है। –

+1

मैंने दूसरे लैम्ब्डा के पैरामीटर के चारों ओर बदल दिया होगा लेकिन यह निश्चित रूप से काम करेगा, कुल मिलाकर एक अविश्वसनीय रूप से शक्तिशाली तरीका है, इसके लंगड़े लोग अक्सर इसका उपयोग नहीं करते हैं –

+1

यह ध्यान दिया जाना चाहिए कि मुझे संदेह है कि कई बार स्थानांतरित करना कॉल नहीं है ऐसा करने का सबसे प्रचलित तरीका। शायद कुछ ऐसा जहां आप एक स्थिर RegEx में सूची की सामग्री बनाते हैं और इसे बदलने के लिए उपयोग करते हैं, तेज़ होगा, लेकिन मुझे संदेह है कि अंतर इस मामले में कोई फर्क नहीं पड़ता। –

0
public static string Trim(string text) 
{ 
    var rv = text; 
    foreach (var ignore in ignoreList) 
     rv = rv.Replace(ignore, ""); 
    return rv; 
} 

Gabe


public static string Trim(string text) 
{ 
    var rv = ""; 
    var words = text.Split(" "); 
    foreach (var word in words) 
    { 
     var present = false; 
     foreach (var ignore in ignoreList) 
     if (word == ignore) 
      present = true; 
     if (!present) 
     rv += word; 
    } 
    return rv; 
} 
+0

कोई LINQ नहीं, RegExp नहीं, फिर भी यह सही है। केवल एक चीज जो मैं बदलूंगा वह खाली स्ट्रिंग का उपयोग शाब्दिक है। –

+7

नहीं, सही नहीं है। यह "123 नॉर्थम्प्टन" को "123 एम्प्टन" में बदल देगा। – Gabe

+0

बंद करें ... अब आपको यह सुनिश्चित करना होगा कि आप शब्दों के बीच की जगह वापस रखें। – Gabe

2

के लिए अपडेट किया गया क्या पाश के लिए एक सरल के साथ गलत क्या है?

string street = "14th Avenue North"; 
foreach (string word in ignoreList) 
{ 
    street = street.Replace(word, string.Empty); 
} 
0

यदि आपके पास कोई सूची है, तो मुझे लगता है कि आपको सभी वस्तुओं को छूना होगा। आप अपने सभी अनदेखा कीवर्ड के साथ एक विशाल RegEx बना सकते हैं और String.Empty पर प्रतिस्थापित कर सकते हैं।

यहाँ एक शुरुआत है:

(^|\s+)(North|South|East|West){1,2}(ern)?(\s+|$) 

आप एक ही रेगुलर एक्सप्रेशन से है, तो शब्दों की उपेक्षा के लिए, आप एक ही प्रत्येक वाक्यांश आप कलन विधि को पारित करने के लिए चाहते हैं के लिए की जगह कर सकते हैं।

+0

मुझे लगता है कि हम कर सकते हैं। क्या हम वास्तव में चाहते हैं, हालांकि? –

+0

यह एक अच्छी शुरुआत है। अब इसे बनाओ ताकि यह केवल पूरे शब्दों से मेल खा सके। – Gabe

+0

हमने डेटा को देखने से उत्पन्न RegEx कीवर्ड के आधार पर ग्राहकों की एक बड़ी सूची को व्यापार या आवासीय के रूप में चिह्नित करने के लिए इस दृष्टिकोण का उपयोग किया। – Brad

6
Regex r = new Regex(string.Join("|", ignoreList.Select(s => Regex.Escape(s)).ToArray())); 
string s = "14th Avenue North"; 
s = r.Replace(s, string.Empty); 
+1

यदि विशेष वर्ण हैं, तो आपको अनदेखा में सामान से बचना चाहिए सूची: string.Join ("|", ignoreList.select (s => Regex.Escape())। ToArray()) –

+0

चूंकि बाधाएं सूची में होंगी 'सेंट' 'जैसे शब्द, भागने की सलाह दी जाती है। और आपको केवल पूरे शब्दों के लिए देखना होगा। – Gabe

+1

@ फ्रैंक सही। । । हालांकि यह वास्तव में निर्दिष्ट नहीं है कि सूची कहां से आती है। जब तक कि सूची वास्तव में जरूरी नहीं है, तब तक इसे सूची से परिवर्तित करने के बजाय पहली बार सही नियमित अभिव्यक्ति लिखना सबसे आसान होगा। – Bob

0

क्यों नहीं इसे आसान रखें?

public static string Trim(string text) 
{ 
    var rv = text.trim(); 
    foreach (var ignore in ignoreList) { 
     if(tv.EndsWith(ignore) { 
     rv = rv.Replace(ignore, string.Empty); 
    } 
    } 
    return rv; 
} 
1

सिर्फ हालांकि तार पाश और एक समय में एक की जगह अगर यह आपकी उदाहरण के रूप में एक छोटी स्ट्रिंग है, आप कर सकते हैं। यदि यह एक बड़ी स्ट्रिंग, कि धीमी गति से किया जाएगा है

address = ignoreList.Aggregate(address, (a, s) => a.Replace(s, String.Empty)); 

: आप कल्पना प्राप्त करना चाहते हैं तो आप यह करने के लिए LINQ सकल विधि का उपयोग कर सकते हैं। इसके बजाय आप स्ट्रिंग के माध्यम से एक ही रन में सभी तारों को प्रतिस्थापित कर सकते हैं, जो बहुत तेज है। मैंने this answer में इसके लिए एक विधि बनाई है।

+0

इसके लिए बहुत बहुत धन्यवाद। मेरी अनदेखी सूची स्पष्ट रूप से मैंने जो पोस्ट की है उससे काफी लंबी होगी, लेकिन यह सुनिश्चित नहीं है कि यह आपकी विधि का उपयोग करने में काफी समय लगेगा। मैं इसे प्रोफाइल करूँगा और देख सकता हूं। –

2

आप जानते हैं कि शब्द की सूची केवल अक्षर हैं जो एक नियमित अभिव्यक्ति के अंदर से बचने की जरूरत नहीं है तो आप ऐसा कर सकते हैं शामिल हैं:

string s = "14th Avenue North"; 
Regex regex = new Regex(string.Format(@"\b({0})\b", 
         string.Join("|", ignoreList.ToArray()))); 
s = regex.Replace(s, ""); 

परिणाम:

 
14th Avenue 

अगर वहाँ विशेष कर रहे हैं पात्रों को आपको दो चीजों को ठीक करने की आवश्यकता होगी:

  • अनदेखा सूची के प्रत्येक तत्व पर Regex.Escape का उपयोग करें।
  • शब्द-सीमा \b एक सफेद जगह से मेल नहीं खाती है जिसके बाद एक प्रतीक या इसके विपरीत होता है। इसके बजाय आपको व्हाट्स स्पेस (या विराम चिह्न जैसे अन्य अलग-अलग वर्णों) की जांच करने की आवश्यकता हो सकती है।

यहाँ इन दोनों समस्याओं को ठीक करने का तरीका देखें:

Regex regex = new Regex(string.Format(@"(?<= |^)({0})(?= |$)", 
    string.Join("|", ignoreList.Select(x => Regex.Escape(x)).ToArray()))); 
+0

यह एक बहुत अच्छी शर्त है कि उनके शब्दों * से बचने की आवश्यकता होगी, क्योंकि वे '" सेंट "," Blvd. "," Rd। "' – Gabe

+0

की तरह होंगे, यह एक और स्थान में उठाई गई अंतरिक्ष समस्या को संभालने का एक शानदार तरीका है टिप्पणी। –

+0

यह बहुत चालाक है और ऐसा लगता है जैसे यह सभी शब्दों पर काम करेगा। मैं इसके लिए कुछ परीक्षण लिखूंगा और इसे ठीक से कोशिश करूँगा। –

0

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

string s = "14th Avenue North" 
ignoreList.ForEach(i => s = s.Replace(i, "")); 
//result is "14th Avenue " 
1

LINQ यह आसान और पठनीय बनाता है। इसके लिए सामान्यीकृत डेटा की आवश्यकता होती है, विशेष रूप से यह केस-संवेदी है।

List<string> ignoreList = new List<string>() 
{ 
    "North", 
    "South", 
    "East", 
    "West" 
};  

string s = "123 West 5th St" 
     .Split(' ') // Separate the words to an array 
     .ToList() // Convert array to TList<> 
     .Except(ignoreList) // Remove ignored keywords 
     .Aggregate((s1, s2) => s1 + " " + s2); // Reconstruct the string 
+1

'.ToList()' अनावश्यक है। – Gabe

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