2014-05-25 96 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

相关问题