Fork me on GitHub

字符串分割(String.Split)时连同分隔符一起返回

今天有个群友问了这个问题:"字符串分割时,如何连同分隔符一起返回?"

我这里写了个String扩展类,模仿原生的Split方法,与原生Split方法的区别在于多了个返回分隔符的枚举功能。

class Program
{
	static void Main(string[] args)
	{
		var flagEx = StringSplitOptionsEx.RemoveEmptyEntries | StringSplitOptionsEx.ReturnSepapator | StringSplitOptionsEx.TrimEntries;
		var result = "  A | B | |C|D".Split("|", flagEx);
		Console.WriteLine(result);
	}
}

[Flags]
public enum StringSplitOptionsEx
{
	None = 0,
	RemoveEmptyEntries = 1,
	TrimEntries = 2,
	ReturnSepapator = 4
}

public static class StringExtensions
{
	private readonly static string[] StringSplitOptionsNames = Enum.GetNames<StringSplitOptions>();

	public static string[] Split(this string str, char separator, StringSplitOptionsEx optionsEx = StringSplitOptionsEx.None)
	{
		return str.Split(separator.ToString(), optionsEx);
	}

	public static string[] Split(this string source, string separator, StringSplitOptionsEx optionsEx = StringSplitOptionsEx.None)
	{
		if (!optionsEx.HasFlag(StringSplitOptionsEx.ReturnSepapator))
		{
			return source.Split(separator, (StringSplitOptions)optionsEx);
		}

		string[] optionsExNames = optionsEx.ToString().Split(',', StringSplitOptions.TrimEntries);
		StringSplitOptions options = optionsExNames.Intersect(StringSplitOptionsNames).Select(t => Enum.Parse<StringSplitOptions>(t)).Aggregate((a, b) => { return a | b; });
		string[] result = source.Split(separator, options);
		if (!optionsEx.HasFlag(StringSplitOptionsEx.ReturnSepapator))
		{
			return result;
		}

		string[] newResult = new string[result.Length * 2 - 1];
		for (int i = 0; i < result.Length; i++)
		{
			newResult[i * 2] = result[i];
		}
		for (int i = 0; i < result.Length - 1; i++)
		{
			newResult[i * 2 + 1] = separator;
		}
		return newResult;
	}

	public static string[] Split(this string source, char[] separators, StringSplitOptionsEx optionsEx = StringSplitOptionsEx.None)
	{
		if (!optionsEx.HasFlag(StringSplitOptionsEx.ReturnSepapator))
		{
			return source.Split(separators, (StringSplitOptions)optionsEx);
		}

		if (optionsEx.HasFlag(StringSplitOptionsEx.RemoveEmptyEntries))
		{
			throw new ArgumentException($"{nameof(StringSplitOptionsEx.RemoveEmptyEntries)} and {StringSplitOptionsEx.ReturnSepapator} cannot be used in combination", nameof(optionsEx));
		}

		string[] optionsExNames = optionsEx.ToString().Split(',', StringSplitOptions.TrimEntries);
		StringSplitOptions options = optionsExNames.Intersect(StringSplitOptionsNames).Select(t => Enum.Parse<StringSplitOptions>(t)).Aggregate((a, b) => { return a | b; });
		string[] result = source.Split(separators, options);

		char[] separatorValues = new char[result.Length - 1];
		int foundCount = 0;
		for (int i = 0; i < source.Length; i++)
		{
			for (int j = 0; j < separators.Length; j++)
			{
				if (source[i] == separators[j])
				{
					separatorValues[foundCount] = separators[j];
					foundCount++;
					break;
				}
			}
		}

		string[] newResult = new string[result.Length * 2 - 1];
		for (int i = 0; i < result.Length; i++)
		{
			newResult[i * 2] = result[i];
		}
		for (int i = 0; i < result.Length - 1; i++)
		{
			newResult[i * 2 + 1] = separatorValues[i].ToString();
		}
		return newResult;
	}
}
output1: 
A
|
B
|
 
|
C
|
D
\
EEEE

output2:
A
|
B
|
C
|
D

posted @ 2021-08-26 10:06  VAllen  阅读(287)  评论(0编辑  收藏  举报