2009-10-13 18 views
15

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

मैं इसे vb.net में कैसे कर सकता हूं?

टैब, न्यूलाइन, आदि सभी को विभाजित किया जाना चाहिए!

यह मुझे थोड़ी देर के लिए परेशान कर रहा है, क्योंकि मेरे वाक्यविन्यास हाइलाइटर मैंने पहली पंक्ति को छोड़कर प्रत्येक पंक्ति में पहले शब्द को पूरी तरह से अनदेखा कर दिया है।

+0

अतिरिक्त व्हाइटस्पेस को हटाने के लिए स्प्लिटस्ट्रिंगऑप्शन के साथ भी संभावित डुप्लिकेट देखें। http://stackoverflow.com/questions/6111298/best-way-to- निर्दिष्ट- whitespace-in-a-string-split-operation – goodeye

उत्तर

22

String.Split() (कोई पैरामीटर) (वामो/सीआर सहित)

+0

उन्होंने इसे अधिभार लॉल के रूप में क्यों शामिल नहीं किया? बहुत बहुत धन्यवाद! – Cyclone

+2

क्योंकि यह एक खाली सरणी के साथ स्प्लिट (पैराम्स []) ओवरलोड को हल करता है। उस अधिभार के लिए प्रलेखन इस व्यवहार का उल्लेख करता है। – Jimmy

+2

सावधानी: जैसा कि जोहान्स रूडोल्फ ने अपने जवाब में उल्लेख किया है, यदि एक पंक्ति में कई सफेद जगह वर्ण हैं, तो स्ट्रिंग। स्प्लिट में खाली तत्व होंगे। यही कारण है कि रूबेन्स फ़ारीस का जवाब बेहतर है। – ToolmakerSteve

18

इस प्रयास करें:

Regex.Split("your string here", "\s+") 
+0

@? @ क्या करता है यह मुझे एक वाक्यविन्यास त्रुटि देता है। – Cyclone

+0

यह सी # है। आपको बिना ठीक होना चाहिए। – Jimmy

+0

क्षमा करें, यह सी # था; आप इसे सुरक्षित रूप से स्ट्रिप कर सकते हैं –

-1
Dim words As String = "This is a list of words, with: a bit of punctuation" + _ 
          vbTab + "and a tab character." + vbNewLine 
Dim split As String() = words.Split(New [Char]() {" "c, CChar(vbTab), CChar(vbNewLine) }) 
+0

काम नहीं किया। अच्छा लगता है हालांकि – Cyclone

+0

क्या मतलब है कि यह काम नहीं करता है? –

+0

यह बस काम नहीं किया। – Cyclone

2

String.Split() हर एक खाली स्थान के पर विभाजित कर देगा सभी खाली स्थान के पर विभाजित करता है, इसलिए परिणाम में आमतौर पर खाली तार होंगे। रेगेक्स समाधान रूबेन फरियास ने इसे करने का सही तरीका दिया है। मैं उसका जवाब upvoted है, लेकिन मैं एक छोटे से अतिरिक्त देने के लिए, regex चीर-फाड़ हैं:

\s एक character class कि सभी खाली स्थान के वर्णों का मिलान करता है।

स्ट्रिंग को सही ढंग से विभाजित करने के लिए जब इसमें शब्दों के बीच एकाधिक व्हाइटस्पेस वर्ण होते हैं, तो हमें शब्दों के बीच सभी व्हाइटस्पेस से मेल खाने के लिए quantifier (या पुनरावृत्ति ऑपरेटर) को विनिर्देशन में जोड़ना होगा। इस मामले में उपयोग करने के लिए सही क्वांटिफ़ायर + है, जिसका अर्थ है किसी दिए गए विनिर्देश के "एक या अधिक" घटनाएं। जबकि सिंटैक्स "\s+" यहां पर्याप्त है, मैं अधिक स्पष्ट "[\s]+" पसंद करता हूं।

+0

सामान्य रूप से, अब हमारे पास दो की बजाय दो समस्याएं हैं ... ;-) –

3

आप regex से बचना चाहते हैं, तो आप इसे इस तरह कर सकते हैं:

"Lorem ipsum dolor sit amet, consectetur adipiscing elit" 
    .Split() 
    .Where(x => x != string.Empty) 

Where() महत्वपूर्ण है के बाद से, अगर आपके स्ट्रिंग कई सफेद स्थान कैरेक्टर हैं अगले एक दूसरे के लिए, यह खाली निकालता है स्ट्रिंग्स जो Split() से परिणामस्वरूप होंगे।

लेखन के समय, वर्तमान में स्वीकृत उत्तर (https://stackoverflow.com/a/1563000/49241) इसे ध्यान में नहीं लेता है।

+2

शानदार समाधान। न केवल रेगेक्स संदर्भ की आवश्यकता से बचता है बल्कि यह भी तेज है (नीचे मेरी पोस्ट देखें)। मैं यह जोड़ना चाहता हूं कि मुझे नहीं लगता कि वीबी लैम्ब्डा ऑपरेटर "=>" का उपयोग करता है, इसलिए इसका वीबी संस्करण थोड़ा अलग है, मुझे ऐसा लगता है: एस। स्प्लिट()। कहां (फंक्शन (एक्स) एक्स <> स्ट्रिंग। लक्षण) – u8it

1

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


खेल में वास्तव में दो कारकों (सिस्टम चर अनदेखी) कर रहे हैं। नीचे प्लॉट किया गया बहुत ही सरल परिदृश्य "ए" का उपयोग दो सफेद स्पेस वर्णों (टैब के बाद एक स्थान) द्वारा सीमित उप-स्ट्रिंग के रूप में करता है। यह निकाले गए उप-तारों की संख्या के प्रभाव को बढ़ाता है। मैं आगे बढ़ गया और मेरे ऑपरेटिंग सिस्टम के लिए निम्नलिखित सामान्य समीकरणों पर पहुंचने के लिए कुछ एकाधिक चर परीक्षण किया।

Regex()
टी = (28.33 * एसएसएल + 572) (एसएसएन/10^6)

स्प्लिट()। कहाँ()
टी = (6।23 * एसएसएल + 250) (एसएसएन/10^6)

जहां टी मिलीसेकंड में निष्पादन समय है, एसएसएल औसत उप-स्ट्रिंग लंबाई है, और एसएसएन स्ट्रिंग में सीमित उप-तारों की संख्या है।

इन समीकरणों के रूप में भी

टी = (28.33 * SL + 572 * एसएसएन)/10^6

और

टी = (6.23 * SL + 250 * एसएसएन) लिखा जा सकता है/10^6

जहां SL कुल स्ट्रिंग लंबाई (SL = SSL * एसएसएन)

निष्कर्ष है: स्प्लिट() कहाँ।() समाधान Regex() से तेज है। प्रमुख कारक उप-तारों की संख्या है, जबकि स्ट्रिंग की लंबाई एक मामूली भूमिका निभाती है। संबंधित गुणांक के लिए प्रदर्शन लाभ लगभग 2x और 5x हैं। (आवश्यकता से शायद रास्ता अधिक सामग्री है, लेकिन यह बहु चर डेटा प्राप्त करने के लिए सेट अप मैं बारे में बात की है)


enter image description here


यहाँ मेरी परीक्षण कोड है

using System; 
using System.Linq; 
using System.Diagnostics; 
using System.Text.RegularExpressions; 
using System.Windows.Forms; 
namespace ConsoleApplication1 
{ 
    class Program 
    { 
     public enum TestMethods {regex, split}; 
     [STAThread] 
     static void Main(string[] args) 
     { 
      //Compare TestMethod execution times and output result information 
      //to the console at runtime and to the clipboard at program finish (so that data is ready to paste into analysis environment) 
      #region Config_Variables 
      //Choose test method from TestMethods enumerator (regex or split) 
      TestMethods TestMethod = TestMethods.split; 
      //Configure RepetitionString 
      String RepetitionString = string.Join(" \t", Enumerable.Repeat("A",100)); 
      //Configure initial and maximum count of string repetitions (final count may not equal max) 
      int RepCountInitial = 100;int RepCountMax = 1000 * 100; 

      //Step increment to next RepCount (calculated as 20% increase from current value) 
      Func<int, int> Step = x => (int)Math.Round(x/5.0, 0); 
      //Execution count used to determine average speed (calculated to adjust down to 1 execution at long execution times) 
      Func<double, int> ExecutionCount = x => (int)(1 + Math.Round(500.0/(x + 1), 0)); 
      #endregion 

      #region NonConfig_Variables 
      string s; 
      string Results = ""; 
      string ResultInfo; 
      double ResultTime = 1; 
      #endregion 

      for (int RepCount = RepCountInitial; RepCount < RepCountMax; RepCount += Step(RepCount)) 
      { 
       s = string.Join("", Enumerable.Repeat(RepetitionString, RepCount)); 
       ResultTime = Test(s, ExecutionCount(ResultTime), TestMethod); 
       ResultInfo = ResultTime.ToString() + "\t" + RepCount.ToString() + "\t" + ExecutionCount(ResultTime).ToString() + "\t" + TestMethod.ToString(); 
       Console.WriteLine(ResultInfo); 
       Results += ResultInfo + "\r\n"; 
      } 
      Clipboard.SetText(Results); 
     } 
     public static double Test(string s, int iMax, TestMethods Method) 
     { 
      switch (Method) 
      { 
       case TestMethods.regex: 
        return Math.Round(RegexRunTime(s, iMax),2); 
       case TestMethods.split: 
        return Math.Round(SplitRunTime(s, iMax),2); 
       default: 
        return -1; 
      } 
     } 
     private static double RegexRunTime(string s, int iMax) 
     { 
      Stopwatch sw = new Stopwatch(); 
      sw.Restart(); 
      for (int i = 0; i < iMax; i++) 
      { 
       System.Collections.Generic.IEnumerable<string> ens = Regex.Split(s, @"\s+"); 
      } 
      sw.Stop(); 
      return Math.Round(sw.ElapsedMilliseconds/(double)iMax, 2); 
     } 
     private static double SplitRunTime(string s,int iMax) 
     { 
      Stopwatch sw = new Stopwatch(); 
      sw.Restart(); 
      for (int i = 0; i < iMax; i++) 
      { 
       System.Collections.Generic.IEnumerable<string> ens = s.Split().Where(x => x != string.Empty); 
      } 
      sw.Stop(); 
      return Math.Round(sw.ElapsedMilliseconds/(double)iMax, 2); 
     } 
    } 
} 
+0

वाह!अच्छा विश्लेषण –

1

मैंने पाया कि मैंने एडम राल्फ द्वारा संदर्भित समाधान का उपयोग किया, साथ ही पी 57 द्वारा नीचे वीबी.नेट टिप्पणी, लेकिन एक विषम अपवाद के साथ। मैंने पाया कि मुझे अंत में .ToList.ToArray जोड़ना था।

तो जैसा:

.Split().Where(Function(x) x <> String.Empty).ToList.ToArray 

कि बिना, मैं हो रही है "'System.String []' 'WhereArrayIterator`1 [System.String]' टाइप करने के लिए प्रकार की वस्तु कास्ट करने में असमर्थ।"

+0

मैं इस काम को केवल तभी ठीक करने में सक्षम था: .Split()। जहां (फ़ंक्शन (x) x <> स्ट्रिंग। लक्षण)। ToArray – Taegost

+0

इसे इंगित करने के लिए धन्यवाद। – Maculin

+0

आपका स्वागत है। मुझे लगता है कि मुझे उस समय भी यह कहना चाहिए था कि यह वीएस2013 और नेट 4.5.2 का उपयोग कर रहा था, बस अगर यह हालिया परिवर्तन था। – Taegost

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