如何使这个功能不会过早分裂?

时间:2010-10-06 07:15:28

标签: c#

我写过这个函数......

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

希望它在空间上分开。

如何修复此功能?

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分: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));
}

我之前尝试将空间推入堆栈,然后对其进行一些检查......但我认为这更容易。