Split a String on 2nd last occurrence of comma in C# - c#

I have a string say
var str = "xy,yz,zx,ab,bc,cd";
and I want to split it on the 2nd last occurrence of a comma in C# i.e
a = "xy,yz,zx,ab"
b = "bc,cd"
How can I achieve this result?

Let's find the required comma index with a help of LastIndexOf:
var str = "xy,yz,zx,ab,bc,cd";
// index of the 2nd last occurrence of ','
int index = str.LastIndexOf(',', str.LastIndexOf(',') - 1);
Then use Substring:
string a = str.Substring(0, index);
string b = str.Substring(index + 1);
Let's have a look:
Console.WriteLine(a);
Comsole.WriteLine(b);
Outcome:
xy,yz,zx,ab
bc,cd

Alternative "readable" approach ;)
const string text = "xy,yz,zx,ab,bc,cd";
var words = text.Split(',');
var firstBatch = Math.Max(words.Length - 2, 0);
var first = string.Join(",", words.Take(firstBatch));
var second = string.Join(",", words.Skip(firstBatch));
first.Should().Be("xy,yz,zx,ab"); // Pass OK
second.Should().Be("bc,cd"); // Pass OK

You could handle this via regex replacement:
var str = "xy,yz,zx,ab,bc,cd";
var a = Regex.Replace(str, #",[^,]+,[^,]+$", "");
var b = Regex.Replace(str, #"^.*,([^,]+,[^,]+)$", "$1");
Console.WriteLine(a);
Console.WriteLine(b);
This prints:
xy,yz,zx,ab
bc,cd

It you get Microsoft's System.Interactive extensions from NuGet then you can do this:
string output = String.Join(",", str.Split(',').TakeLast(2));

Related

How do I replace word in string except first occurrence using c#

How do I replace word in string except first occurrence using c#
for example
string s= "hello my name is hello my name hello";
replace hello with x
output should be string news = "hello my name is x my name x";
I tried like works fine
string originalStr = "hello my hello ditch hello";
string temp = "hello";
string str = originalStr.Substring(0, originalStr.IndexOf(temp) + temp.Length);
originalStr = str + originalStr.Substring(str.Length).Replace(temp, "x");
can I have Regex expression for above code ?
This will do it for a general pattern:
var matchPattern = Regex.Escape("llo");
var replacePattern = string.Format("(?<={0}.*){0}", matchPattern);
var regex = new Regex(replacePattern);
var newText = regex.Replace("hello llo llo", "x");
If you want to only match and replace whole words, edit your pattern accordingly:
var matchPattern = #"\b" + Regex.Escape("hello") + #"\b";
Try this:
string pat = "hello";
string tgt = "x";
string tmp = s.Substring(s.IndexOf(pat)+pat.Length);
s = s.Replace(tmp, tmp.Replace(pat,tgt));
tmp is the substring of the original string starting after the end of first occurrence of the pattern to be replaced (pat). We then replace pat with the desired value (tgt) within this substring, and replace the substring in the original string with this updated value.
Demo
Do you need regex? You could use this little LINQ query and String.Join:
int wordCount = 0;
var newWords = s.Split()
.Select(word => word != "hello" || ++wordCount == 1 ? word : "x");
string newText = string.Join(" ", newWords);
But note that this will replace all white-spaces (even tabs or newlines) with a space.

Extracting parts of a string c#

In C# what would be the best way of splitting this sort of string?
%%x%%a,b,c,d
So that I end up with the value between the %% AND another variable containing everything right of the second %%
i.e. var x = "x"; var y = "a,b,c,d"
Where a,b,c.. could be an infinite comma seperated list. I need to extract the list and the value between the two double-percentage signs.
(To combat the infinite part, I thought perhaps seperating the string out to: %%x%% and a,b,c,d. At this point I can just use something like this to get X.
var tag = "%%";
var startTag = tag;
int startIndex = s.IndexOf(startTag) + startTag.Length;
int endIndex = s.IndexOf(tag, startIndex);
return s.Substring(startIndex, endIndex - startIndex);
Would the best approach be to use regex or use lots of indexOf and substring to do the extracting based on te static %% characters?
Given that what you want is "x,a,b,c,d" the Split() function is actually pretty powerful and regex would be overkill for this.
Here's an example:
string test = "%%x%%a,b,c,d";
string[] result = test.Split(new char[] { '%', ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string s in result) {
Console.WriteLine(s);
}
Basicly we ask it to split by both '%' and ',' and ignore empty results (eg. the result between "%%"). Here's the result:
x
a
b
c
d
To Extract X:
If %% is always at the start then;
string s = "%%x%%a,b,c,d,h";
s = s.Substring(2,s.LastIndexOf("%%")-2);
//Console.WriteLine(s);
Else;
string s = "v,u,m,n,%%x%%a,b,c,d,h";
s = s.Substring(s.IndexOf("%%")+2,s.LastIndexOf("%%")-s.IndexOf("%%")-2);
//Console.WriteLine(s);
If you need to get them all at once then use this;
string s = "m,n,%%x%%a,b,c,d";
var myList = s.ToArray()
.Where(c=> (c != '%' && c!=','))
.Select(c=>c).ToList();
This'll let you do it all in one go:
string pattern = "^%%(.+?)%%(?:(.+?)(?:,|$))*$";
string input = "%%x%%a,b,c,d";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
// "x"
string first = match.Groups[1].Value;
// { "a", "b", "c", "d" }
string[] repeated = match.Groups[2].Captures.Cast<Capture>()
.Select(c => c.Value).ToArray();
}
You can use the char.IsLetter to get all the list of letter
string test = "%%x%%a,b,c,d";
var l = test.Where(c => char.IsLetter(c)).ToArray();
var output = string.Join(", ", l.OrderBy(c => c));
Since you want the value between the %% and everything after in separate variables and you don't need to parse the CSV, I think a RegEx solution would be your best choice.
var inputString = #"%%x%%a,b,c,d";
var regExPattern = #"^%%(?<x>.+)%%(?<csv>.+)$";
var match = Regex.Match(inputString, regExPattern);
foreach (var item in match.Groups)
{
Console.WriteLine(item);
}
The pattern has 2 named groups called x and csv, so rather than just looping, you can easily reference them by name and assign them to values:
var x = match.Groups["x"];
var y = match.Groups["csv"];

All elements before last comma in a string in c#

How can i get all elements before comma(,) in a string in c#?
For e.g.
if my string is say
string s = "a,b,c,d";
then I want all the element before d i.e. before the last comma.So my new string shout look like
string new_string = "a,b,c";
I have tried split but with that i can only one particular element at a time.
string new_string = s.Remove(s.LastIndexOf(','));
If you want everything before the last occurrence, use:
int lastIndex = input.LastIndexOf(',');
if (lastIndex == -1)
{
// Handle case with no commas
}
else
{
string beforeLastIndex = input.Substring(0, lastIndex);
...
}
Use the follwoing regex: "(.*),"
Regex rgx = new Regex("(.*),");
string s = "a,b,c,d";
Console.WriteLine(rgx.Match(s).Groups[1].Value);
You can also try:
string s = "a,b,c,d";
string[] strArr = s.Split(',');
Array.Resize(strArr, Math.Max(strArr.Length - 1, 1))
string truncatedS = string.join(",", strArr);

String Search & replacement

I have a string "JohnMarkMarkMark"
I want to replace the "Mark" with "Tom" with two cases
In first case i want to replace only first occurance of "Mark" Result will be: "JohnTomMarkMark"
In the second case i want to replace all the occurance of "Mark" Result will be: "JohnTomTomTom"
Please suggest
Thnaks
string data = "JohnMarkMarkMark";
string resultOne = new Regex("Mark").Replace(data, "Tom", 1);
string resultAll = data.Replace("Mark", "Tom");
For the first case, use IndexOf, Substring and Concat.
For the second case, use Replace.
(1) is:
var inString = "TestMarkMarkMark";
var lookFor = "Mark";
var replaceWith = "Tom";
var length = lookFor.Length;
var first = inString.IndexOf(lookFor);
var newString = inString.Substring(0, first) + replaceWith + inString.Substring(first + length);
Which could be optimized, but I've expanded it out so it's easy to follow.
(2) is trivial - just do inString.Replace("Mark", "Tom");
for case 1 try this
string s = "JohnMarkMarkMark";
Regex x = new Regex("Mark");
MatchCollection m = x.Matches(s);
if (m!=null && m.Count > 0)
{
s = s.Remove(m[0].Index, m[0].Length);
s = s.Insert(m[0].Index,"Tom");
}
for case 2 try s = s.Replace("Mark","Tom");

How to split for only one string without using arrays

I've a string 01-India. I want to split on '-' and get only the code 01. How can I do this. I'm a .net newbie. Split function returns a array. Since I need only one string, how can this be done. Is there a ingenious way to do it using split only. Or do I've to use substring only?
Other possibility is
string xy = "01-India";
string xz = xy.Split('-')[0];
You can search for the first occurence of - and then use the method substring to cut the piece out.
var result = input.Substring(0, input.IndexOf('-'))
string str = "01-India";
string prefix = null;
int pos = str.IndexOf('-');
if (pos != -1)
prefix = str.SubString(0,pos);
var str = "01-India";
var hyphenIndex = str.IndexOf("-");
var start = str.substring(0, hyphenIndex);
or you can use regular expression if it is a more complicated string pattern.
Something like this?
var s = "01-India";
var result = s.SubString(0, s.IndexOf("-"));
Since you don't want to use arrays, you could do an IndexOf('-') and then a substring.
string s = "01-India"
int index = s.IndexOf('-');
string code = s.Substring(0, index);
Or, for added fun, you could use String.Remove.
string s = "01-India"
int index = s.IndexOf('-');
string code = s.Remove(index);
string value = "01-India";
string part1 = value.Split('-')[0];

Categories