2014-05-25 95 views
-1

嗨,大家好,我一直在試圖看看我是否可以拆分一個字符串,將分隔符作爲新字符串數組中的單獨元素,但發現它很困難。這正是我想達到....分割一個字符串,並保留分隔符

如果我有串"8*(4+x)+7"什麼...

我將與運營商和括號分割,並得到類似... "8","*", "(", "4", "+", "x", ")", "+", "7" ....

我已經閱讀了很多關於如何使用Regex.Split來解決這個問題的答案,並且嘗試了很多,但是我沒有得到我想要的。

+0

你不」 t需要分割字符串。告訴是否拆分不一定要使用? – Hassan

+1

我沒有注意到任何分裂。看起來你只是想要一個字符數組。您可以使用'foreach'枚舉一個字符串,或者調用'MyString.ToCharArray()'。 – Silvermind

+1

@Silvermind - 他可能希望像「10」這樣的數字保持爲單獨的字符串。 – Enigmativity

回答

1
string str = "8400*(413+x)+700"; 
List<string> lstArray = new List<string>(); 

for(int i=0; i<str.Length; i++) 
{ 
     if (Char.IsNumber(str[i])) 
     { 
      string sNum = str[i].ToString(); 

      if ((i + 1) < str.Length) 
      { 
       for (int k = i+1; k < str.Length; k++) 
       { 
        if (Char.IsNumber(str[k]) == true) 
        { 
         sNum += str[k].ToString(); 
         i = i + 1; 
        } 
        else 
         break; 
        } 
      } 
      lstArray.Add(sNum); 
     } 
     else if (Char.IsSymbol(str[i])) 
     { 
      lstArray.Add(str[i].ToString());         
     } 
     else if (Char.IsLetter(str[i])) 
     { 
      string sLetter = str[i].ToString(); 

      if ((i + 1) < str.Length) 
      { 
       for (int k = i + 1; k < str.Length; k++) 
       { 
        if (Char.IsLetter(str[k]) == true) 
        { 
         sLetter += str[k].ToString(); 
         i = i + 1; 
        } 
        else 
         break; 
       } 
      } 
      lstArray.Add(sLetter); 
     } 
     else if (Char.IsPunctuation(str[i])) 
     {     
      lstArray.Add(str[i].ToString()); 
     } 
    } 

上面的代碼應該工作。 打印具有值之間用逗號名單應該是這樣的:

Console.WriteLine(string.Join(",", lstArray.ToArray())); 

這裏是例如輸入和輸出:

//Input  
8400*(413+xyz)+700 

//Output 
8400,*,(,413,+,xyz,),+,700 

,或者你可以遍歷lstArray

foreach(string s in lstArray) 
    Console.WriteLine(s); 
+0

@ user2864740能解釋一下嗎? – Hassan

+0

就像我說的數字可能包括數字10,所以這不會工作 – Ken4scholars

+0

@ user2864740,請檢查更新的答案。謝謝糾正。 – Hassan

3

唐分割 - 匹配!

var equation = "8 * (42+xyz)+7"; 
var tokens = Regex.Matches(equation, @"\d+|\w+|\S") 
    .OfType<Match>() 
    .Select(m => m.Value); 

regular expression pattern匹配

  • 一系列數字之一 - 例如842
  • 一系列單詞字符 - 例如xyz(它也將匹配x_2
  • 單個非空白字符 - 例如*(

匹配被執行多次(經由Matches),並且每個匹配成功的值被選擇成將所得IEnumerable<string>

與傳統斯普利特不同,這種方法沒有明確的分隔符,因爲分隔僅由每場比賽停止和下一場比賽開始的位置決定。這也是爲什麼白色空間被跳過的原因:它只是不匹配。

要明確指定運算符或「分隔符」,只需用[+*()](僅匹配指定的運算符和括號)模式替換\S(它與任何非空白字符匹配)即可。

儘管這是一個非常簡單的標記器,可以完成所請求的任務,但在此階段添加其他lexeme信息通常很有用。

+0

它會返回什麼?一個字符串數組?以及在哪裏列出分隔符 – Ken4scholars

+0

它將返回一個'IEnumerable '。這種方法沒有分離器 - 每個比賽會「吃」多少,因爲分離取決於每場比賽*停止的位置*。 – user2864740

+0

謝謝,但這也不會工作,如果我有一個標識符X2,它將分開x和2 – Ken4scholars

1

這工作:

Func<IEnumerable<string>, IEnumerable<char>, IEnumerable<string>> split = null; 
split = (ss, cs) => 
{ 
    if (!cs.Any()) 
    { 
     return ss; 
    } 
    else 
    { 
     var c = cs.First(); 
     return ss.SelectMany(s0 => 
     { 
      var parts = s0.Split(c); 
      return split(
       parts 
        .Take(1) 
        .Concat(
         parts 
          .Skip(1) 
          .SelectMany(p => new [] { new string(c, 1), p })), 
       cs.Skip(1)); 
     }) 
     .Where(s0 => !String.IsNullOrWhiteSpace(s0)); 
    } 
}; 

(請注意split的雙重分配是必要的,因爲這是一個遞歸函數。)

所以,如果我開始與此:

var s = "80*(45+xy)+27"; 
var separators = "*+-/()"; 

我可以這樣做:

var result = split(new [] { s }, separators); 

我結束了與此:

result

+0

謝謝......我會試試看看它是如何工作的。 – Ken4scholars

+0

請讓我真的是新手編程,所以我很抱歉,如果我的一些問題聽起來很愚蠢....什麼是CS和SS? – Ken4scholars

+0

@ user3442256 - 它們是匿名方法「split」的參數。這就好像我宣佈一種新方法,簽名爲IEnumerable split(IEnumerable ss,IEnumerable cs)''。 – Enigmativity

相關問題