【问题标题】:How to split a string not losing separator characters using BCL in C#?如何在 C# 中使用 BCL 拆分字符串而不丢失分隔符?
【发布时间】:2011-10-13 04:11:29
【问题描述】:

我需要根据分隔符的某些字符数组来拆分字符串,并且不会在字符串中丢失这些分隔符。即:

string: "Hello world!"
separators: " !"
result: ("Hello", " ", "world", "!")

当然,我可以编写一些通过该字符串并返回我需要的结果的东西,但是是否已经有一些东西允许我这样做,比如神奇地配置了String.Split

更新:我需要不使用正则表达式的解决方案,因为它对我来说非常慢。

【问题讨论】:

  • 一个细节:如果源字符串是“”,你会期望什么输出(一个空字符串和一个分隔符,或者只有一个空格)?
  • @Dream:我认为使用正则表达式比使用自定义解决方案“如果您不倾向于使用一些不安全的上下文和指针”更快......此外,通过使用正则表达式,您可以避免不可预知的错误我发生在自定义解决方案中..

标签: c# .net string split separator


【解决方案1】:

使用正则表达式:

string[] parts = Regex.Split(myString, yourPattern);

测试:

string[] parts = Regex.Split("Hello World!", "(!| )");

输出:

Hello
" "//just space
World
!
""//empty string

【讨论】:

  • 如果你不需要IgnoreCase,我认为你不应该使用它。可能会降低性能。另外:它并没有完全回答这个问题。
  • -1 再次被删除。虽然 OP 也在 ' ' 处分裂。虽然2它可能需要一些解释为什么括号很重要。
  • @Jalal Aldeen Saa'd,看看我关于正则表达式的更新
【解决方案2】:

一个 linq 解决方案:

var s = "Hello world!";
char[] separators = { ' ', '!' };

string current = string.Empty;
List<string> result = s.Aggregate(new List<string>(), (list, ch) =>
    {
        if (separators.Contains(ch))
        {
            list.Add(current);
            list.Add(ch.ToString());
            current = string.Empty;
        }
        else current += ch;
        return list;
    }, list => list);

【讨论】:

    【解决方案3】:

    这将是一个纯粹的程序解决方案:

    private static IEnumerable<string> Tokenize(string text, string separators)
    {
        int startIdx = 0;
        int currentIdx = 0;
    
        while (currentIdx < text.Length)
        {
            // found a separator?
            if (separators.Contains(text[currentIdx]))
            {
                // yield a substring, if it's not empty
                if (currentIdx > startIdx)
                    yield return text.Substring(startIdx, currentIdx - startIdx);
    
                // yield the separator
                yield return text.Substring(currentIdx, 1);
    
                // mark the beginning of the next token
                startIdx = currentIdx + 1;
            }
    
            currentIdx++;
        }
    }
    

    请注意,此解决方案避免返回 empty 标记。例如,如果输入是:

    string input = "test!!";
    

    调用Tokenize(input, "!") 将返回三个令牌:

    test
    !
    !
    

    如果要求两个相邻分隔符之间应有一个空标记,则应删除if (currentIdx &gt; startIdx) 条件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-06
      • 2017-05-29
      • 2012-03-01
      • 1970-01-01
      相关资源
      最近更新 更多