在我编写自己的函数之前,只想检查.NET库中是否存在类似string.split(string input, params int[] indexes)
的函数?
这个函数应该在我传递给它的索引上拆分字符串。
编辑:我不应该添加string.join句子 - 这很令人困惑。
答案 0 :(得分:13)
您可以使用String
实例方法Substring。
string a = input.Substring(0, 10);
string b = input.Substring(10, 5);
string c = input.Substring(15, 3);
答案 1 :(得分:5)
所有其他答案似乎太复杂了,所以我采取了刺。
./program --some-option --verbose --file="./myfile.txt" > ./output.txt 2> ./debug.out
答案 2 :(得分:2)
Split方法根据识别模式划分字符串。完美打破逗号分隔列表等。
但你是对的,没有内置的字符串方法来实现你想要的。
答案 3 :(得分:1)
一种可能的解决方案:
public static class StringExtension
{
public static string[] Split(this string source, params int[] sizes)
{
var length = sizes.Sum();
if (length > source.Length) return null;
var resultSize = sizes.Length;
if (length < source.Length) resultSize++;
var result = new string[resultSize];
var start = 0;
for (var i = 0; i < resultSize; i++)
{
if (i + 1 == resultSize)
{
result[i] = source.Substring(start);
break;
}
result[i] = source.Substring(start, sizes[i]);
start += sizes[i];
}
return result;
}
}
答案 4 :(得分:0)
总是有正则表达式。
以下是一个可以扩展的示例:
string text = "0123456789ABCDEF";
Match m = new Regex("(.{7})(.{4})(.{5})").Match(text);
if (m.Success)
{
var result = new string[m.Groups.Count - 1];
for (var i = 1; i < m.Groups.Count; i++)
result[i - 1] = m.Groups[i].Value;
}
这是一个封装上述逻辑的函数:
public static string[] SplitAt(this string text, params int[] indexes)
{
var pattern = new StringBuilder();
var lastIndex = 0;
foreach (var index in indexes)
{
pattern.AppendFormat("(.{{{0}}})", index - lastIndex);
lastIndex = index;
}
pattern.Append("(.+)");
var match = new Regex(pattern.ToString()).Match(text);
if (! match.Success)
{
throw new ArgumentException("text cannot be split by given indexes");
}
var result = new string[match.Groups.Count - 1];
for (var i = 1; i < match.Groups.Count; i++)
result[i - 1] = match.Groups[i].Value;
return result;
}
这写得相当快,但我相信这说明了我的观点并强调了我对评论作者迈克尔的观点。
答案 5 :(得分:0)
这不会直接回答您的概括性问题,但最有可能是最常见的情况(或至少在我遇到此问题时我正在寻找答案的情况) ),其中indexes
是单个int
,这种扩展方法比返回string[]
数组要干净一些,尤其是在C#7中。
对于它的价值,我使用string.Substring()
进行了基准测试,以创建两个char[]
数组,调用text.CopyTo()
并通过调用new string(charArray)
返回两个字符串。使用string.Substring()
的速度大约是以前的两倍。
public static class StringExtensions
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static (string left, string right) SplitAt(this string text, int index) =>
(text.Substring(0, index), text.Substring(index));
}
public static class Program
{
public static void Main()
{
var (left, right) = "leftright".SplitAt(4);
Console.WriteLine(left);
Console.WriteLine(right);
}
}
注意:在C#7之前的版本中使用Tuple<string, string>
不会在冗长的方式上节省很多,实际上返回一个string[2]
数组可能更干净。
public static class StringExtensions
{
// I'd use one or the other of these methods, and whichever one you choose,
// rename it to SplitAt()
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Tuple<string, string> TupleSplitAt(this string text, int index) =>
Tuple.Create<string, string>(text.Substring(0, index), text.Substring(index));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string[] ArraySplitAt(this string text, int index) =>
new string[] { text.Substring(0, index), text.Substring(index) };
}
public static class Program
{
public static void Main()
{
Tuple<string, string> stringsTuple = "leftright".TupleSplitAt(4);
Console.WriteLine("Tuple method");
Console.WriteLine(stringsTuple.Item1);
Console.WriteLine(stringsTuple.Item2);
Console.WriteLine();
Console.WriteLine("Array method");
string[] stringsArray = "leftright".ArraySplitAt(4);
Console.WriteLine(stringsArray[0]);
Console.WriteLine(stringsArray[1]);
}
}
答案 6 :(得分:0)
public static IEnumerable<string> SplitAt(this string source, params int[] index)
{
var indices = new[] { 0 }.Union(index).Union(new[] { source.Length });
return indices
.Zip(indices.Skip(1), (a, b) => (a, b))
.Select(_ => source.Substring(_.a, _.b - _.a));
}
var s = "abcd";
s.SplitAt(); // "abcd"
s.SplitAt(0); // "abcd"
s.SplitAt(1); // "a", "bcd"
s.SplitAt(2); // "ab", "cd"
s.SplitAt(1, 2) // "a", "b", "cd"
s.SplitAt(3); // "abc", "d"
答案 7 :(得分:0)
以“ List
来电者
string iTextLine = "02121AAAARobert Louis StevensonXXXX"
int[] tempListIndex = new int[] {
// 0 - // 0number (exclude first)
5, // 1user
9, // 2name
31 // role
};
// GET - words from indexes
List<string> tempWords = getListWordsFromLine(iTextLine, tempListIndex);
方法
/// <summary>
/// GET - split line in parts using index cuts
/// </summary>
/// <param name="iListIndex">Input List of indexes</param>
/// <param name="iTextLine">Input line to split</param>
public static List<string> getListWordsFromLine(string iTextLine, int[] iListIndex)
{
// INIT
List<string> retObj = new List<string>();
int currStartPos = 0;
// GET - clear index list from dupl. and sort it
int[] tempListIndex = iListIndex.Distinct()
.OrderBy(o => o)
.ToArray();
// CTRL
if (tempListIndex.Length != iListIndex.Length)
{
// ERR
throw new Exception("Input iListIndex contains duplicate indexes");
}
for (int jj = 0; jj < tempListIndex.Length; ++jj)
{
try
{
// SET - line chunk
retObj.Add(iTextLine.Substring(currStartPos,
tempListIndex[jj] - currStartPos));
}
catch (Exception)
{
// SET - line is shorter than expected
retObj.Add(string.Empty);
}
// GET - update start position
currStartPos = tempListIndex[jj];
}
// SET
retObj.Add(iTextLine.Substring(currStartPos));
// RET
return retObj;
}