Is the string separated by index / parameters?

Just before you write your own function, you just need to check if a function such as string.split(string input, params int[] indexes) exists in the .NET library? This function should split the string into indexes that I pass to it.

Edit: I shouldn't have added the string.join clause - it was confused.

+8
source share
8 answers

You can use the String Substring instance method.

 string a = input.Substring(0, 10); string b = input.Substring(10, 5); string c = input.Substring(15, 3); 
+13
source

All the other answers seemed too complicated, so I took a hit.

 using System.Linq; public static class StringExtensions { /// <summary> /// Returns a string array that contains the substrings in this instance that are delimited by specified indexes. /// </summary> /// <param name="source">The original string.</param> /// <param name="index">An index that delimits the substrings in this string.</param> /// <returns>An array whose elements contain the substrings in this instance that are delimited by one or more indexes.</returns> /// <exception cref="ArgumentNullException"><paramref name="index" /> is null.</exception> /// <exception cref="ArgumentOutOfRangeException">An <paramref name="index" /> is less than zero or greater than the length of this instance.</exception> public static string[] SplitAt(this string source, params int[] index) { index = index.Distinct().OrderBy(x => x).ToArray(); string[] output = new string[index.Length + 1]; int pos = 0; for (int i = 0; i < index.Length; pos = index[i++]) output[i] = source.Substring(pos, index[i] - pos); output[index.Length] = source.Substring(pos); return output; } } 
+5
source

The Split method divides a string based on a recognition pattern. Ideal for splitting comma-separated lists, etc.

But you're right, there are no built-in string methods to achieve what you want.

+2
source

One possible solution:

 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; } } 
+1
source

There are always regular expressions.

Here is an example from which you can deploy:

  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; } 

Here's a function that encapsulates the above logic:

  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; } 

It was written fairly quickly, but I believe that it illustrates my points and emphasizes my comments on the commentary author, Michael.

0
source

This does not give a direct answer to your generalized question, but in the most likely case (or at least in the case when I was looking for an answer when I came across this SO question), where indexes is one int , this extension The method is a little cleaner than returning the string[] array, especially in C # 7.

Whatever the cost, I string.Substring() use string.Substring() against creating two char[] arrays, calling text.CopyTo() and returning two lines by calling new string(charArray) . Using string.Substring() was about twice as fast.

C # 7 Syntax

jdoodle.com example

 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 # 6 Syntax

jdoodle.com example

Note. Using Tuple<string, string> in versions prior to C # 7 does not save a lot of verbosity, and in fact it may be easier to return an array of 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]); } } 
0
source
 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" 
0
source

Version with "List <string>" as return.

a guest

 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); 

method

 /// <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; } 
0
source

All Articles