I want to split a string after a word, not after the character.
Example string:
A-quick-brown-fox-jumps-over-the-lazy-dog
I want to split the string after "jumps-"
can I use the stringname.Split("jumps-") function?
I want the following output:
over-the-lazy-dog.
I suggest using IndexOf and Substring since you actually want a suffix ("String after word"), not a split:
string source = "A-quick-brown-fox-jumps-over-the-lazy-dog";
string split = "jumps-";
// over-the-lazy-dog
string result = source.Substring(source.IndexOf(split) + split.Length);
var theString = "A-quick-brown-fox-jumps-over-the-lazy-dog.";
var afterJumps = theString.Split(new[] { "jumps-" }, StringSplitOptions.None)[1]; //Index 0 would be what is before 'jumps-', index 1 is after.
I usually use extension methods:
public static string join(this string[] strings, string delimiter) { return string.Join(delimiter, strings); }
public static string[] splitR(this string str, params string[] delimiters) { return str.Split(delimiters, StringSplitOptions.RemoveEmptyEntries); }
//public static string[] splitL(this string str, string delimiter = " ", int limit = -1) { return vb.Strings.Split(str, delimiter, limit); }
public static string before(this string str, string delimiter) { int i = (str ?? ""). IndexOf(delimiter ?? ""); return i < 0 ? str : str.Remove (i ); } // or return str.splitR(delimiter).First();
public static string after (this string str, string delimiter) { int i = (str ?? "").LastIndexOf(delimiter ?? ""); return i < 0 ? str : str.Substring(i + delimiter.Length); } // or return str.splitR(delimiter).Last();
sample use:
stringname.after("jumps-").splitR("-"); // splitR removes empty entries
You could extend the Split() method. In fact, I did this a few months ago. Probably not the prettiest code but it gets the job done. This method splits at every jumps-, not just at the first one.
public static class StringExtensions
{
public static string[] Split(this String Source, string Separator)
{
if (String.IsNullOrEmpty(Source))
throw new Exception("Source string is null or empty!");
if (String.IsNullOrEmpty(Separator))
throw new Exception("Separator string is null or empty!");
char[] _separator = Separator.ToArray();
int LastMatch = 0;
List<string> Result = new List<string>();
Func<char[], char[], bool> Matches = (source1, source2) =>
{
for (int i = 0; i < source1.Length; i++)
{
if (source1[i] != source2[i])
return false;
}
return true;
};
for (int i = 0; _separator.Length + i < Source.Length; i++)
{
if (Matches(_separator.ToArray(), Source.Substring(i, _separator.Length).ToArray()))
{
Result.Add(Source.Substring(LastMatch, i - LastMatch));
LastMatch = i + _separator.Length;
}
}
Result.Add(Source.Substring(LastMatch, Source.Length - LastMatch));
return Result.ToArray();
}
}
Related
I have list like this:
List<string> myList = new List<string>()
{
"AS2258B43C014AI9954803",
"AS2258B43C014AI9954603",
"AS2258B43C014AI9954703",
"AS2258B43C014AI9954503",
"AS2258B43C014AI9954403",
"AS2258B43C014AI9954203",
"AS2258B43C014AI9954303",
"AS2258B43C014AI9954103",
};
I want to output something format is sameString+diffString0\diffString1\diffString2.... like this "AS2258B43C014AI9954803\603\703\503\403\203\303\103"
what should I do?
You can create a method which returns you the difference between to strings:
private static string GetDiff (string s1, string s2)
{
int i;
for(i = 0; i < Math.Min(s1.Length,s2.Length); i++)
{
if(s1[i] != s2[i])
{
break;
}
}
return s2.Substring(i);
}
This method iterats until the first character which is different and returns the remaining characters of the second string.
With that method, you can obtain your result with the LINQ query:
string first = myList[0];
string result = first + "/" + string.Join("/", myList.Skip(1).Select(x => GetDiff(first,x)));
Online demo: https://dotnetfiddle.net/TPkhmz
Alphanumeric sorting using LINQ
Create static method for pads
public static string PadNumbers(string input)
{
return Regex.Replace(input, "[0-9]+", match => match.Value.PadLeft(10, '0'));
}
then call it
var result = myList.OrderBy(x => PadNumbers(x));
after that you can find the difference
The simplest solution is to create a function like this :
public static string Output(List<String> ListString)
{
string sameString = ListString.First().Substring(0, 18);
string output = sameString;
foreach (var item in ListString)
{
output += item.Substring(19);
output += "\\";
}
return output.Substring(0, output.Length - 1);
}
In c#, is there an elegant way to split a string like "a.b.c" into a, a.b, a.b.c
The number of separators are not fixed so it could be "a.b" which will output {a, a.b} or "a.b.c.d" which will output {a, a.b, a.b.c, a.b.c.d}.
The only thing I can think of is split the string into individual components and then concatenate it again.
This is what I have so far:
var fieldNames = new List<string>();
var fieldSeparator ='.';
var myString = "a.b.c.d";
var individualFields = myString.Split(fieldSeparator);
string name = "";
foreach(var fieldName in individualFields)
{
name = string.IsNullOrEmpty(name) ? fieldName : $"{name}{fieldSeparator}{fieldName}";
fieldNames.Add(name);
}
Maybe this extension?
public static string[] SplitCombineFirst(this string str, params string[] delimiter)
{
string[] tokens = str.Split(delimiter, StringSplitOptions.RemoveEmptyEntries);
var allCombinations = new List<string>(tokens.Length);
for(int take = 1; take <= tokens.Length; take++)
{
string combination = string.Join(delimiter[0], tokens.Take(take));
allCombinations.Add(combination);
}
return allCombinations.ToArray();
}
Call:
string[] result = "a.b.c".SplitCombineFirst(".");
This looks like a classic case for recursion.
List<string> splitCombine(string source, string delimiter, int startIndex)
{
List<string> result = new List<string>();
var indx = source.IndexOf(delimiter, startIndex);
if (indx >= 0)
{
if (indx > 0)
{
result.Add(source.Substring(0, indx));
}
result.AddRange(splitCombine(source, delimiter, ++indx));
}
else
{
result.Add(source);
}
return result;
}
Call:
var result = splitCombine("a.b.c.d.e", ".", 0);
I'm trying to develop a method that will match all strings between two strings:
I've tried this but it returns only the first match:
string ExtractString(string s, string start,string end)
{
// You should check for errors in real-world code, omitted for brevity
int startIndex = s.IndexOf(start) + start.Length;
int endIndex = s.IndexOf(end, startIndex);
return s.Substring(startIndex, endIndex - startIndex);
}
Let's suppose we have this string
String Text = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2"
I would like a c# function doing the following :
public List<string> ExtractFromString(String Text,String Start, String End)
{
List<string> Matched = new List<string>();
.
.
.
return Matched;
}
// Example of use
ExtractFromString("A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2","A1","A2")
// Will return :
// FIRSTSTRING
// SECONDSTRING
// THIRDSTRING
Thank you for your help !
private static List<string> ExtractFromBody(string body, string start, string end)
{
List<string> matched = new List<string>();
int indexStart = 0;
int indexEnd = 0;
bool exit = false;
while (!exit)
{
indexStart = body.IndexOf(start);
if (indexStart != -1)
{
indexEnd = indexStart + body.Substring(indexStart).IndexOf(end);
matched.Add(body.Substring(indexStart + start.Length, indexEnd - indexStart - start.Length));
body = body.Substring(indexEnd + end.Length);
}
else
{
exit = true;
}
}
return matched;
}
Here is a solution using RegEx. Don't forget to include the following using statement.
using System.Text.RegularExpressions
It will correctly return only text between the start and end strings given.
Will not be returned:
akslakhflkshdflhksdf
Will be returned:
FIRSTSTRING
SECONDSTRING
THIRDSTRING
It uses the regular expression pattern [start string].+?[end string]
The start and end strings are escaped in case they contain regular expression special characters.
private static List<string> ExtractFromString(string source, string start, string end)
{
var results = new List<string>();
string pattern = string.Format(
"{0}({1}){2}",
Regex.Escape(start),
".+?",
Regex.Escape(end));
foreach (Match m in Regex.Matches(source, pattern))
{
results.Add(m.Groups[1].Value);
}
return results;
}
You could make that into an extension method of String like this:
public static class StringExtensionMethods
{
public static List<string> EverythingBetween(this string source, string start, string end)
{
var results = new List<string>();
string pattern = string.Format(
"{0}({1}){2}",
Regex.Escape(start),
".+?",
Regex.Escape(end));
foreach (Match m in Regex.Matches(source, pattern))
{
results.Add(m.Groups[1].Value);
}
return results;
}
}
Usage:
string source = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2";
string start = "A1";
string end = "A2";
List<string> results = source.EverythingBetween(start, end);
text.Split(new[] {"A1", "A2"}, StringSplitOptions.RemoveEmptyEntries);
You can split the string into an array using the start identifier in following code:
String str = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2";
String[] arr = str.Split("A1");
Then iterate through your array and remove the last 2 characters of each string (to remove the A2). You'll also need to discard the first array element as it will be empty assuming the string starts with A1.
Code is untested, currently on a mobile
This is a generic solution, and I believe more readable code. Not tested, so beware.
public static IEnumerable<IList<T>> SplitBy<T>(this IEnumerable<T> source,
Func<T, bool> startPredicate,
Func<T, bool> endPredicate,
bool includeDelimiter)
{
var l = new List<T>();
foreach (var s in source)
{
if (startPredicate(s))
{
if (l.Any())
{
l = new List<T>();
}
l.Add(s);
}
else if (l.Any())
{
l.Add(s);
}
if (endPredicate(s))
{
if (includeDelimiter)
yield return l;
else
yield return l.GetRange(1, l.Count - 2);
l = new List<T>();
}
}
}
In your case you can call,
var text = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2";
var splits = text.SplitBy(x => x == "A1", x => x == "A2", false);
This is not the most efficient when you do not want the delimiter to be included (like your case) in result but efficient for opposite cases. To speed up your case one can directly call the GetEnumerator and make use of MoveNext.
I'm trying to develop a method that will match all strings between two strings:
I've tried this but it returns only the first match:
string ExtractString(string s, string start,string end)
{
// You should check for errors in real-world code, omitted for brevity
int startIndex = s.IndexOf(start) + start.Length;
int endIndex = s.IndexOf(end, startIndex);
return s.Substring(startIndex, endIndex - startIndex);
}
Let's suppose we have this string
String Text = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2"
I would like a c# function doing the following :
public List<string> ExtractFromString(String Text,String Start, String End)
{
List<string> Matched = new List<string>();
.
.
.
return Matched;
}
// Example of use
ExtractFromString("A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2","A1","A2")
// Will return :
// FIRSTSTRING
// SECONDSTRING
// THIRDSTRING
Thank you for your help !
private static List<string> ExtractFromBody(string body, string start, string end)
{
List<string> matched = new List<string>();
int indexStart = 0;
int indexEnd = 0;
bool exit = false;
while (!exit)
{
indexStart = body.IndexOf(start);
if (indexStart != -1)
{
indexEnd = indexStart + body.Substring(indexStart).IndexOf(end);
matched.Add(body.Substring(indexStart + start.Length, indexEnd - indexStart - start.Length));
body = body.Substring(indexEnd + end.Length);
}
else
{
exit = true;
}
}
return matched;
}
Here is a solution using RegEx. Don't forget to include the following using statement.
using System.Text.RegularExpressions
It will correctly return only text between the start and end strings given.
Will not be returned:
akslakhflkshdflhksdf
Will be returned:
FIRSTSTRING
SECONDSTRING
THIRDSTRING
It uses the regular expression pattern [start string].+?[end string]
The start and end strings are escaped in case they contain regular expression special characters.
private static List<string> ExtractFromString(string source, string start, string end)
{
var results = new List<string>();
string pattern = string.Format(
"{0}({1}){2}",
Regex.Escape(start),
".+?",
Regex.Escape(end));
foreach (Match m in Regex.Matches(source, pattern))
{
results.Add(m.Groups[1].Value);
}
return results;
}
You could make that into an extension method of String like this:
public static class StringExtensionMethods
{
public static List<string> EverythingBetween(this string source, string start, string end)
{
var results = new List<string>();
string pattern = string.Format(
"{0}({1}){2}",
Regex.Escape(start),
".+?",
Regex.Escape(end));
foreach (Match m in Regex.Matches(source, pattern))
{
results.Add(m.Groups[1].Value);
}
return results;
}
}
Usage:
string source = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2";
string start = "A1";
string end = "A2";
List<string> results = source.EverythingBetween(start, end);
text.Split(new[] {"A1", "A2"}, StringSplitOptions.RemoveEmptyEntries);
You can split the string into an array using the start identifier in following code:
String str = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2";
String[] arr = str.Split("A1");
Then iterate through your array and remove the last 2 characters of each string (to remove the A2). You'll also need to discard the first array element as it will be empty assuming the string starts with A1.
Code is untested, currently on a mobile
This is a generic solution, and I believe more readable code. Not tested, so beware.
public static IEnumerable<IList<T>> SplitBy<T>(this IEnumerable<T> source,
Func<T, bool> startPredicate,
Func<T, bool> endPredicate,
bool includeDelimiter)
{
var l = new List<T>();
foreach (var s in source)
{
if (startPredicate(s))
{
if (l.Any())
{
l = new List<T>();
}
l.Add(s);
}
else if (l.Any())
{
l.Add(s);
}
if (endPredicate(s))
{
if (includeDelimiter)
yield return l;
else
yield return l.GetRange(1, l.Count - 2);
l = new List<T>();
}
}
}
In your case you can call,
var text = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2";
var splits = text.SplitBy(x => x == "A1", x => x == "A2", false);
This is not the most efficient when you do not want the delimiter to be included (like your case) in result but efficient for opposite cases. To speed up your case one can directly call the GetEnumerator and make use of MoveNext.
I have a string as follows:
string str = "abcdefgh"
and I would like to reduce the size to only two chars - so the output would be:
str = "ab"
string str = "abcdefgh";
var s = str.Substring(0, 2);
Or another solution is to write Your Own extension method (that would check if string longer than expected substring and avoid the exception as athoik has noticed) and do this
class Program
{
static void Main(string[] args)
{
var str = "asdfasd";
var trimmed = str.MySubString(2);
Console.WriteLine(trimmed);
Console.ReadLine();
}
}
public static class Helper
{
public static string MySubString(this String value, int length)
{
return !string.IsNullOrEmpty(value) && value.Length >= length
? value.Substring(0, length)
: value;
}
}
string sub = str.Substring(0, 2);
string substr = str.substring(0,2)
or
StringBuilder sb = new StringBuilder();
sb.toString(0,2);