2010-10-06 42 views
1

我已经写了这个功能...如何使这个功能不会过早拆分?

internal static IEnumerable<KeyValuePair<char?, string>> SplitUnescaped(this string input, char[] separators) 
{ 
    int index = 0; 
    var state = new Stack<char>(); 

    for (int i = 0; i < input.Length; ++i) 
    { 
     char c = input[i]; 
     char s = state.Count > 0 ? state.Peek() : default(char); 

     if (state.Count > 0 && (s == '\\' || (s == '[' && c == ']') || ((s == '"' || s == '\'') && c == s))) 
      state.Pop(); 
     else if (c == '\\' || c == '[' || c == '"' || c == '\'') 
      state.Push(c); 
     if (state.Count == 0 && separators.Contains(c)) 
     { 
      yield return new KeyValuePair<char?, string>(c, input.Substring(index, i - index)); 
      index = i + 1; 
     } 
    } 

    yield return new KeyValuePair<char?, string>(null, input.Substring(index)); 
} 

,因为他们没能逃脱,引号,或者括号其将在给定的分隔字符串,只要。似乎工作得很好,但它有一个问题。

有字符我想拆就包括空间:

{ '>', '+', '~', ' ' }; 

因此,考虑到字符串

a > b 

我想它拆就>而忽略了空间,但鉴于

a b 

想要它spli在空间上。

我该如何修复这个功能?

+2

做一些布尔“最后一个字符有分裂”,如果它被设置不分裂。那会把'a> b'分成'a'和'> b'这不是你想要的。但是,如果不是,你想'a> b'被分割为'a'和'b'?那么'a>> b'呢? – 2010-10-06 07:24:08

+0

是的,我想'a> b'分成'a'和'b'。 'a>> b'在我的语法中不是有效的输入,所以我真的不在乎这种情况会发生什么(除了空格之外,只能有'部分'之间的一个分隔字符) – mpen 2010-10-06 07:30:58

回答

0

您可以继续根据>进行拆分,然后删除空的字符串。

+0

问题在于它需要返回'''作为'KeyValuePair'的一部分,而不是空间。 – mpen 2010-10-06 07:28:25

+0

删除其他分隔符之前和之后出现的空格怎么样? a> b变成a> b,ab保持为ab – Prashast 2010-10-06 07:31:30

+1

我想到了这一点,但问题在于引用字符串中的空格像''a> b“'是重要的,不应该被删除(或拆分) 。 – mpen 2010-10-06 07:41:14

0

我认为这确实是...

internal static IEnumerable<KeyValuePair<char?, string>> SplitUnescaped(this string input, char[] separators) 
{ 
    int startIndex = 0; 
    var state = new Stack<char>(); 
    input = input.Trim(separators); 

    for (int i = 0; i < input.Length; ++i) 
    { 
     char c = input[i]; 
     char s = state.Count > 0 ? state.Peek() : default(char); 

     if (state.Count > 0 && (s == '\\' || (s == '[' && c == ']') || ((s == '"' || s == '\'') && c == s))) 
      state.Pop(); 
     else if (c == '\\' || c == '[' || c == '"' || c == '\'') 
      state.Push(c); 
     else if (state.Count == 0 && separators.Contains(c)) 
     { 
      int endIndex = i; 
      while (input[i] == ' ' && separators.Contains(input[i + 1])) { ++i; } 
      yield return new KeyValuePair<char?, string>(input[i], input.Substring(startIndex, endIndex - startIndex)); 
      while (input[++i] == ' ') { } 
      startIndex = i; 
     } 
    } 

    yield return new KeyValuePair<char?, string>(null, input.Substring(startIndex)); 
} 

我尝试过之前的空间压入堆栈,然后做针对一些检查...但我认为这是比较容易。

+0

这里也有一个错误...这个函数将在这里保持http://code.google.com/p/sharp-query/source/browse/trunk/SharpQuery/SharpQuery2/SharpQuery.cs#74而不是..至少在一段时间内。 – mpen 2010-10-07 00:03:48