Split string by List:
I have SplitColl with delimeters:
xx
yy
..
..
And string like this:
strxx
When i try to split string:
var formattedText = "strxx";
var lst = new List<String>();
lst.Add("xx");
lst.Add("yy");
var arr = formattedText.Split(lst.ToArray(), 10, StringSplitOptions.RemoveEmptyEntries);
I have "str" result;
But how to skip this result? I want to get empty array in this case (when delim is a part of a word).
I expect, that when formattedText="str xx", result is str.
EDIT:
I have a many delimeters of address: such as street,city,town,etc.
And i try to get strings like: city DC-> DC.
But, when i get a word like:cityacdc-> i get acdc, but it not a name of a city.
It seems that you are not using your keywords really as delimiters but as search criterion. In this case you could use RegEx to search for each pattern. Here is an example program to illustrate this procedure:
static void Main(string[] args)
{
List<string> delim = new List<string> { "city", "street" };
string formattedText = "strxx street BakerStreet cityxx city London";
List<string> results = new List<string>();
foreach (var del in delim)
{
string s = Regex.Match(formattedText, del + #"\s\w+\b").Value;
if (!String.IsNullOrWhiteSpace(s))
{
results.Add(s.Split(' ')[1]);
}
}
Console.WriteLine(String.Join("\n", results));
Console.ReadKey();
}
This would handle this case:
And I try to get strings like: city DC --> DC
to handle the case where you want to find the word in front of your keyword:
I expect, that when formattedText="str xx", result is str
just switch the places of the matching criterion:
string s = Regex.Match(formattedText, #"\b\w+\s"+ del).Value;
and take the first element at the split
results.Add(s.Split(' ')[0]);
Give this a try, basically what I'm doing is first I remove any leading or tailing delimiters (only if they are separated with a space) from the formattedText string. Then using the remaining string I split it for each delimiter if it has spaces on both sides.
//usage
var result = FormatText(formattedText, delimiterlst);
//code
static string[] FormatText(string input, List<string> delimiters)
{
delimiters.ForEach(d => {
TrimInput(ref input, "start", d.ToCharArray());
TrimInput(ref input, "end", d.ToCharArray());
});
return input.Split(delimiters.Select(d => $" {d} ").ToArray(), 10, StringSplitOptions.RemoveEmptyEntries);
}
static void TrimInput(ref string input, string pos, char[] delimiter)
{
//backup
string temp = input;
//trim
input = (pos == "start") ? input.TrimStart(delimiter) : input.TrimEnd(delimiter);
string trimmed = (pos == "start") ? input.TrimStart() : input.TrimEnd();
//update string
input = (input != trimmed) ? trimmed : temp;
}
Related
string input = "Hello World";
input.Reverse().ToArray();
string[] output = input.Split();
string s1 = string.Join(" ", output);
Console.WriteLine(s1.Reverse().ToArray());
It would print ==>"dlroW olleH".
Per the comment
var input = "Hello World";
var output = string.Join(
" ",
input.Split().Select(
w => string.Concat(w.Reverse())
)
);
This splits the string to words, reverses each word (resulting in a list of chars that is string.Concat'd back to being a reversed word string) and then re joins them with space separators
Spread out to multiple lines:
var words = input.Split();
var rwords = words.Select(w => string.Concat(w.Reverse()));
var output = string.Join(" ", rwords);
Use Runes to simplify handling any string encoding problems.
public static string ReverseEachWord(this string str)
{
// Open a buffer the same length as the input string
var sb = new StringBuilder(str.Length);
// Open a FILO (First-In, Last-Out) collection to reverse each word
var stack = new Stack<Rune>();
foreach (var rune in str.EnumerateRunes())
{
if (Rune.IsWhiteSpace(rune))
{
// Write the reversed word to the buffer...
while (stack.TryPop(out var stackRune))
{
sb.Append(stackRune);
}
// ... and the space
sb.Append(rune);
}
else
{
// Put on top of the stack
stack.Push(rune);
}
}
// Dump the buffer to a new string
return sb.ToString();
}
I have c# strings that look like this:
"かたむく;かたぶく[ok]"
"そば[側,傍];そく[側];はた"
"くすり"
"おととい[gikun];おとつい[gikun];いっさくじつ"
How can I trim these down so that the output has only text up to the first occurrence of a ";" character (not a normal semicolon) or a "[" or if neither are present then the new string would be the same as the existing.
"かたむく"
"そば"
"くすり"
"おととい"
Is that something that would be best done with Regex or should I use some indexOf type of code to do this?
You don't need a Regex, just string.IndexOfAny. Something like:
var inputs = new[]
{
"かたむく;かたぶく[ok]",
"そば[側,傍];そく[側];はた",
"くすり",
"おととい[gikun];おとつい[gikun];いっさくじつ"
};
var separators = new[] {' ', '['};
foreach (var input in inputs)
{
var separatorPosition = input.IndexOfAny(separators);
if (separatorPosition >= 0)
{
Debug.WriteLine($"Split: {input.Substring(0, separatorPosition)}");
}
else
{
Debug.WriteLine($"No Split: {input}");
}
}
I get the following output from your inputs:
Split: かたむく;かたぶく
Split: そば
No Split: くすり
Split: おととい
It doesn't quite match what you show, but I think it's correct (and what you show isn't)
Expanding on my comment, "IndexOf can be used to find the first index of the [ character, and Substring can return the string up to that point."
public static string GetSubstringToChar(string input, char delimeter = '[')
{
if (input == null || !input.Contains(delimeter)) return input;
return input.Substring(0, input.IndexOf(delimeter));
}
To make this work with multiple delimeters, we can pass in an array of delimeter characters and use IndexOfAny:
public static string GetSubstringToChar(string input, char[] delimeters)
{
if (input == null || !input.Any(delimeters.Contains)) return input;
return input.Substring(0, input.IndexOfAny(delimeters));
}
You could then call this like:
var strings = new List<string>
{
"かたむく;かたぶく[ok]",
"そば[側,傍];そく[側];はた",
"くすり",
"おととい[gikun];おとつい[gikun];いっさくじつ",
};
var delimeters = new[] { ';', '[' };
foreach (var str in strings)
{
Console.WriteLine(GetSubstringToChar(str, delimeters));
}
An extension method with a little validation will do the job.
public static string GetUntil(this string input, char[] delimiters)
{
if (input == null || input.IndexOfAny(delimiters) == -1)
return input;
else
return input.Split(delimiters)[0];
}
then call like:
var test = "かたむく;かたぶく[ok]".GetUntil(new char[] { ' ', '[' });
I have a string which look likes
E-1,E-2,F-3,F-1,G-1,E-2,F-5
Now i want output in array like
E, F, G
I only want the name of character once that appears in the string.
My Code Sample is as follows
string str1 = "E-1,E-2,F-3,F-1,G-1,E-2,F-5";
string[] newtmpSTR = str1.Split(new char[] { ',' });
Dictionary<string, string> tmpDict = new Dictionary<string, string>();
foreach(string str in newtmpSTR){
string[] tmpCharPart = str.Split('-');
if(!tmpDict.ContainsKey(tmpCharPart[0])){
tmpDict.Add(tmpCharPart[0], "");
}
}
Is there any easy way to do it in c#, using string function, If yes the how
string input = "E-1,E-2,F-3,F-1,G-1,E-2,F-5";
string[] splitted = input.Split(new char[] { ',' });
var letters = splitted.Select(s => s.Substring(0, 1)).Distinct().ToList();
Maybe you can obtain the same result with a regular expression! :-)
Updated: Thank you for the answer, but I disagree that my question is answered by another thread. "Multiple delimiters" and "Multi-Character delimiters" are 2 different questions.
This is my code so far:
List<string> delimiters = new List<string>();
List<string> data = new List<string>
{
"Car|cBlue,Mazda~Model|m3",
//More data
};
string userInput = "";
int i = 1;
//The user can enter a maximum of 5 delimiters
while (userInput != "go" && i <= 5)
{
userInput = Console.ReadLine();
delimiters.Add(userInput);
i++;
}
foreach (string delimiter in delimiters)
{
foreach (string s in data)
{
//This split is not working
//string output[] = s.Split(delimiter);
}
}
So, if the user enters "|c" and "~", the expected output is: "Car", "Blue,Mazda", "Model|m3"
If the user enters "|c", "|m", and ",", then the expected output will be: "Car", "Blue", "Mazda~Model", "3"
Add the user input into the List delimiters.
string data = "Car|cBlue,Mazda~Model|m3";
List<string> delimiters = new List<string>();
delimiters.Add("|c");//Change this to user input
delimiters.Add("|m");//change this to user input
string[] parts = data.Split(delimiters.ToArray(), StringSplitOptions.RemoveEmptyEntries);
foreach (string item in parts)
{
Console.WriteLine(item);
}
String.Split has an overload that does exactly that - you just need to convert your List<string> to a string[] :
string input = "Car|cBlue,Mazda~Model|m3";
List<string> delims = new List<string> {"|c", "~"};
string[] out1 = input.Split(delims.ToArray(),StringSplitOptions.None);
//output:
// Car
// Blue,Mazda
// Model|m3
delims = new List<string> {"|c", "|m", ","};
string[] out2 = input.Split(delims.ToArray(),StringSplitOptions.None).Dump();
//output:
// Car
// Blue
// Mazda~Model
// 3
You can use SelectMany to get the result from all the data strings and ToArray() method to create an array from delimiters
var result = data.SelectMany(s => s.Split(delimiters.ToArray(), StringSplitOptions.None));
In the following example,
/*----------------------// kvkbl jk//bv klb /* /*gkljbgflkjbncviogf*/
how do I get the strings between /* and */?
Take a look at this tutorial
using System;
class Program
{
static void Main()
{
string s = "/*there*/ is a cat";
string s = "User name (sales)";
int start = s.IndexOf("/*");
int end = s.IndexOf(")*/")
string result = s.substring(start, end - start -1)
//result contains "there"
}
}
string s = "there is a cat";
//
// Split string on spaces.
// ... This will separate all the words.
//
string[] words = s.Split(' ');
foreach (string word in words)
{
Console.WriteLine(word);
}
//Output
there
is
a
cat