2010-08-25 13 views
5

में मैं नीचे स्ट्रिंगस्ट्रिंग स्प्लिटर नेट

P,MV,A1ZWR,MAV#(X,,), PV,MOV#(X,12,33),LO 

मैं

P 

MV 

A1ZWR 

MAV#(X,,) 

PV 

MOV#(X,12,33) 

LO 

के रूप में उत्पादन के रूप में है कि यह आसानी से बंटवारे द्वारा किया जा सकता बाहर कर किया जा सकता है की जरूरत है "," लेकिन समस्या

जब यह एमएवी # (एक्स,) या MOV # (एक्स, 12,33) प्रकार है।

कृपया मदद

उत्तर

4

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

string data = "P,MV,A1ZWR,MAV#(X,,), PV,MOV#(X,12,33),LO"; 

int depth = 0; 
int group = 0; 

var result = data 
    .GroupBy(x => { 
     if (x == '(') depth++; 
     if (x == ')') depth--; 
     if (x == ',' && depth == 0) group++; 
     return group; }) 
    .Select(x => new String(x.ToArray()).Trim(' ', ',')) 
0

एक विभक्त चरित्र है कि अपने प्रविष्टियों का हिस्सा नहीं होंगे प्रयोग करें।

P~MV~A1ZWR~MAV#(X,,)~ PV~MOV#(X,12,33)~LO 

या यहां तक ​​कि एक अदृश्य चरित्र (0x00?)

+0

एक समस्या के रूप में यह भी पी के रूप में आ सकता है!, एमवी ~, MOB # (एक्स, 9,8) –

2

बेस्ट शर्त डेटा के लिए एक पार्सर लिखने के लिए है। एक सीएसवी पार्सिंग लाइब्रेरी देखें, आप शायद के बजाय #(...) का समर्थन करने के लिए बहुत अधिक कठिनाई के बिना संशोधित कर सकते हैं।

0

यदि यह एक फ़ाइल है जिसे आप पॉप्युलेट कर रहे हैं, तो एक डिलीमीटर का उपयोग करें जो कोई समस्या नहीं होगी, जैसे | उदाहरण के लिए। यदि यह एक फ़ाइल है जिसे आप स्कैनिंग और पार्सिंग कर रहे हैं, तो संभवतः आप आवश्यक डेटा खींचने के लिए नियमित अभिव्यक्तियों का उपयोग कर सकते हैं।

यदि नहीं, तो आपको तारों को विभाजित करना होगा और मुद्दों की तलाश करते समय बाल्टी को देखना होगा और किसी भी आवश्यक विलय और आगे विभाजन करना होगा।

8

आप विभाजक के बीच मूल्यों से मेल खाने के लिए नियमित अभिव्यक्ति का उपयोग कर सकते हैं, और निर्दिष्ट कर सकते हैं कि पैराथेस के भीतर सब कुछ मूल्य का हिस्सा है। उदाहरण:

string data = "P,MV,A1ZWR,MAV#(X,,), PV,MOV#(X,12,33),LO"; 

foreach (Match m in Regex.Matches(data, @"\s*((\(.*?\)|[^,])*)(,|$)")) { 
    Console.WriteLine(m.Groups[1].Value); 
} 

आउटपुट:

P 
MV 
A1ZWR 
MAV#(X,,) 
PV 
MOV#(X,12,33) 
LO 
+3

हालांकि यह है कि इस जैसे ही वहाँ नेस्टेड रहते हैं टूट जाएगा उल्लेख किया जाना चाहिए नहीं है कोष्ठक। साथ ही, डिजाइन के मामले में, यह आपके समाधान की कमी है कि यह छोड़ने/गायब प्रविष्टियों (फेंकने के बजाए) चुपचाप विफल हो जाएगा। – Timwi

+0

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

1

कैसे पाशन और जैसे ( और ) ट्रेडमार्क वर्ण का पता लगाने के बारे में: में

string[] test = "P,MV,A1ZWR,MAV#(X,,), PV,MOV#(X,12,33),LO".Split(','); 

bool insideElement = false; 
string insideElementResult = ""; 
List<string> result = new List<string>(); 
foreach (string s in test) 
{ 
    //Determine context: 
    if (s.IndexOf("(") > -1) 
     insideElement = true; 

    //Determine where to add my nice string 
    if (!insideElement) 
     result.Add(s); 
    else 
     insideElementResult += s; 

    //Determine if contact has ended: 
    if (s.IndexOf(")") > -1) 
    { 
     insideElement = false; 
     result.Add(insideElementResult); 
     insideElementResult = null; 
    } 
    else if (insideElement) 
    { 
     insideElementResult += ","; 
    } 

} 

परिणाम:

[0] "P" string 
    [1] "MV" string 
    [2] "A1ZWR" string 
    [3] "MAV#(X,,)" string 
    [4] " PV" string 
    [5] "MOV#(X,12,33)" string 
    [6] "LO" string 

दी, regex के रूप में के रूप में पसंद नहीं है, और भीतरी कोष्ठक पर टूट जाएगा, लेकिन हे, यह काम करता है;)

4
string input = "P,MV,A1ZWR,MAV#(X,,), PV,MOV#(X,12,33),LO"; 
IList<string> parts = new List<string>(); 
int paranthesisCount = 0; 
int lastSplitIndex = 0; 
for (int i = 0; i < input.Length; i++) 
{ 
    if (input[i] == '(') 
    { 
     paranthesisCount++; 
     continue; 
    } 
    if (input[i] == ')') 
    { 
     paranthesisCount--; 
     continue; 
    } 
    if (input[i] == ',' && paranthesisCount == 0) 
    { 
     parts.Add(input.Substring(lastSplitIndex, i - lastSplitIndex)); 
     lastSplitIndex = i + 1; 
    } 
} 
if (input.Length - lastSplitIndex > 0) 
{ 
    parts.Add(input.Substring(lastSplitIndex, input.Length - lastSplitIndex)); 
} 
+2

+1। हालांकि, यह ध्यान दिया जाना चाहिए कि अगर एक करीबी-संश्लेषण गायब हो तो यह चुपचाप असफल हो जाएगा। – Timwi

1

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

  1. सभी कोष्ठक ठीक
  2. कोई गलत विभाजन occour
  3. सभी टोकन सही कर रहे हैं हो सकता है (कि सहायक हो सकता है, लेकिन आवेदन पर निर्भर करता है)

एक अच्छा पार्सर जिसमें त्रुटि जांच है, वह आपके लिए विशिष्ट भाषा के लिए xsd है।

मैंने ANTLR के साथ एक पार्सर किया है।अगर यह आपकी मदद करता है तो इसे देखें। यह समस्या पर एक overkill हो सकता है। बस इसके बारे में सोचो।

0

इस समारोह सभी टोकन बाहर कर देगा, यकीन है कि वहाँ टोकन के बीच कोई डबल अल्पविराम का कर रहे हैं, और सुनिश्चित करें कि सभी कोष्ठक बंद किये गये हैं है। यह थोड़ा लंबा है।

IEnumerable<string> Tokenise(string input) 
{ 
    const char tokenlimiter = ','; 
    const char funcstart = '#'; 
    const char funcend = ')'; 
    StringBuilder token = new StringBuilder(5); 
    bool gotfunc = false; 
    bool gotone = false; 
    int pos = 0; 
    int opened = 0; 
    foreach(char c in input) 
    { 
     if (c == funcstart) 
     { 
      gotfunc = true; 
      opened++; 
     } 
     if(c == funcend) 
     { 
      gotfunc = false; 
      opened--; 
     } 
     if(!gotfunc && c == tokenlimiter) 
     { 
      gotone = true; 
      if(token.Length == 0) 
      { 
       throw new ArgumentException("Blank instruction at " + pos, input); 
      } 
      yield return token.ToString(); 
     } 
     if(gotone) 
     { 
      token = new StringBuilder(5); 
      gotone = false; 
     } 
     else 
     { 
      token.Append(c);  
     } 
     if(pos == input.Length - 1) 
     { 
      if (!gotfunc && opened == 0 && c != tokenlimiter) 
      { 
       yield return token.ToString(); 
      } 
      else if (gotfunc || opened != 0) 
      { 
       throw new ArgumentException("Broken function", input); 
      } 
      else 
      { 
       throw new ArgumentException("Blank instruction at " + pos, input); 
      } 
     } 
     pos++; 
    } 

} 
0
private static void CreateListString(string s) 
{ 
string[] splits = s.Split(new char[] { ',' }); 
List<string> strs = new List<string>(); 
bool isLimiterSeen = false; 
StringBuilder str = null; 
for (int i = 0; i < splits.Length; i++) 
{ 
if (splits[i].Contains("#(")) 
{ 
isLimiterSeen = true; 
str = new StringBuilder(); 
} 
if (!isLimiterSeen) 
strs.Add(splits[i]); 
else 
{ 
str = str.Append("," + splits[i]); 
if (splits[i].EndsWith(")")) 
{ 
if (str.ToString().StartsWith(",")) 
strs.Add(str.ToString().Substring(1)); 
else 
strs.Add(str.ToString()); 
isLimiterSeen = false; 
str = null; 
} 
} 
} 
} 
संबंधित मुद्दे