使用分隔符拆分字符串,但在C#中保留结果中的分隔符

时间:2011-01-13 12:41:09

标签: c# string split

我想用分隔符拆分字符串,但在结果中保留分隔符。

我如何在C#中执行此操作?

8 个答案:

答案 0 :(得分:21)

如果您希望分隔符为“自己的分割”,则可以使用Regex.Split例如:

string input = "plum-pear";
string pattern = "(-)";

string[] substrings = Regex.Split(input, pattern);    // Split on hyphens
foreach (string match in substrings)
{
   Console.WriteLine("'{0}'", match);
}
// The method writes the following to the console:
//    'plum'
//    '-'
//    'pear'

答案 1 :(得分:4)

此版本不使用LINQ或Regex,因此它可能相对有效。我认为它可能比正则表达式更容易使用,因为您不必担心转义特殊分隔符。它返回IList<string>,这比总是转换为数组更有效。这是一种方便的扩展方法。您可以将分隔符作为数组或多个参数传递。

/// <summary>
/// Splits the given string into a list of substrings, while outputting the splitting
/// delimiters (each in its own string) as well. It's just like String.Split() except
/// the delimiters are preserved. No empty strings are output.</summary>
/// <param name="s">String to parse. Can be null or empty.</param>
/// <param name="delimiters">The delimiting characters. Can be an empty array.</param>
/// <returns></returns>
public static IList<string> SplitAndKeepDelimiters(this string s, params char[] delimiters)
{
    var parts = new List<string>();
    if (!string.IsNullOrEmpty(s))
    {
        int iFirst = 0;
        do
        {
            int iLast = s.IndexOfAny(delimiters, iFirst);
            if (iLast >= 0)
            {
                if (iLast > iFirst)
                    parts.Add(s.Substring(iFirst, iLast - iFirst)); //part before the delimiter
                parts.Add(new string(s[iLast], 1));//the delimiter
                iFirst = iLast + 1;
                continue;
            }

            //No delimiters were found, but at least one character remains. Add the rest and stop.
            parts.Add(s.Substring(iFirst, s.Length - iFirst));
            break;

        } while (iFirst < s.Length);
    }

    return parts;
}

一些单元测试:

text = "[a link|http://www.google.com]";
result = text.SplitAndKeepDelimiters('[', '|', ']');
Assert.IsTrue(result.Count == 5);
Assert.AreEqual(result[0], "[");
Assert.AreEqual(result[1], "a link");
Assert.AreEqual(result[2], "|");
Assert.AreEqual(result[3], "http://www.google.com");
Assert.AreEqual(result[4], "]");

答案 2 :(得分:2)

我想说实现这个的最简单的方法(除了Hans Kesting提出的论点)是以常规方式拆分字符串,然后遍历数组并将分隔符添加到除最后一个元素之外的每个元素。

答案 3 :(得分:0)

我想做一个像这样的多行字符串,但需要保留换行符,所以我做了这个

string x = 
@"line 1 {0}
line 2 {1}
";

foreach(var line in string.Format(x, "one", "two")
    .Split("\n") 
    .Select(x => x.Contains('\r') ? x + '\n' : x)
    .AsEnumerable()
) {
    Console.Write(line);
}

产量

line 1 one
line 2 two

答案 4 :(得分:0)

我遇到了同样的问题,但有多个分隔符。这是我的解决方案:

    public static string[] SplitLeft(this string @this, char[] delimiters, int count)
    {
        var splits = new List<string>();
        int next = -1;
        while (splits.Count + 1 < count && (next = @this.IndexOfAny(delimiters, next + 1)) >= 0)
        {
            splits.Add(@this.Substring(0, next));
            @this = new string(@this.Skip(next).ToArray());
        }
        splits.Add(@this);
        return splits.ToArray();
    }

分离CamelCase变量名的示例:

var variableSplit = variableName.SplitLeft(
    Enumerable.Range('A', 26).Select(i => (char)i).ToArray());

答案 5 :(得分:0)

为避免在新行中添加字符,请尝试以下操作:

 string[] substrings = Regex.Split(input,@"(?<=[-])");

答案 6 :(得分:0)

我将此代码编写为分割并保留定界符

private static string[] SplitKeepDelimiters(string toSplit, char[] delimiters, StringSplitOptions splitOptions = StringSplitOptions.None)
{
    var tokens = new List<string>();
    int idx = 0;
    for (int i = 0; i < toSplit.Length; ++i)
    {
        if (delimiters.Contains(toSplit[i]))
        {
            tokens.Add(toSplit.Substring(idx, i - idx));  // token found
            tokens.Add(toSplit[i].ToString());            // delimiter
            idx = i + 1;                                  // start idx for the next token
        }
    }

    // last token
    tokens.Add(toSplit.Substring(idx));

    if (splitOptions == StringSplitOptions.RemoveEmptyEntries)
    {
        tokens = tokens.Where(token => token.Length > 0).ToList();
    }

    return tokens.ToArray();
}

用法示例:

string toSplit = "AAA,BBB,CCC;DD;,EE,";
char[] delimiters = new char[] {',', ';'};
string[] tokens = SplitKeepDelimiters(toSplit, delimiters, StringSplitOptions.RemoveEmptyEntries);
foreach (var token in tokens)
{
    Console.WriteLine(token);
}

答案 7 :(得分:0)

veggerby的答案修改为

  • 列表中没有字符串项目
  • 具有固定的字符串作为分隔符,例如“ ab”,而不是单个字符
var delimiter = "ab";
var text = "ab33ab9ab"
var parts = Regex.Split(text, $@"({Regex.Escape(delimiter)})")
                 .Where(p => p != string.Empty)
                 .ToList();

// parts = "ab", "33", "ab", "9", "ab"

如果Regex.Escape()出现在分隔符中,以防正则表达式解释为特殊模式命令的字符(例如*(),因此必须转义。