input (string) : 1 2 3 4 5
I want be :
string line = "1 2 3 4 5";
list<int>list = new list<int>();
list.Add(1);
list.Add(2);
list.Add(3);
list.Add(4);
list.Add(5);
You may use a Regular Expression to identify the occurrences of integer numbers within the text. Here's a working example.
This may prove to be much more reliable depending on your scenario, e.g. you could type arbitrary words/text in there, and it would still find all numbers.
The C# code to do this would be as follows:
List<int> FindIntegers(string input)
{
Regex regex = new Regex(#"(\d+)");
List<int> result = new List<int>();
foreach (Match match in regex.Matches(input))
{
result.Add(int.Parse(match.Value));
}
return result;
}
You can use the Split method with the StringSplitOptions overload:
string line = "1 2 3 4 5";
char[] delim = {' '};
var list = line.Split(delim, StringSplitOptions.RemoveEmptyEntries)
.Select(i => Convert.ToInt32(i)).ToList();
RemoveEmptyEntries will skip over the blank entries and your output will be:
List<Int32> (5 items)
1
2
3
4
5
See String.Split Method on MSDN for more info.
You can convert multiple spaces to single ones and then split on ' ':
var result = Regex.Replace(line, #"\s+", " ").Split(' ').Select(x => int.Parse(x.ToString())).ToList();
Or directly select all numbers by one of these Regexes:
\d{1} --> If the numbers will always consist of a single digit.
\d+ --> If the numbers might contain more than one digit.
Like this:
var result = new List<int>();
foreach (Match i in Regex.Matches(line, #"\d{1}")) // Or the other Regex...
{
result.Add(int.Parse(i.Value));
}
You can split the line on spaces removing empty matches with StringSplitOptions.RemoveEmptyEntries.
string line = "1 2 3 4 5";
var list = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
.Select(n => Convert.ToInt32(n)).ToList();
So the result will have only the numbers then you can convert to int.
Try this using lambda expression and string split
string line = "1 2 3 4 5";
List<int> list= line.Split(" ").Where(x => x.Trim().length > 0).Select(x => Convert.ToInt32(x)).ToList();
Related
So I have a server that receives a connection with the message being converted to a string, I then have this string split between by the spaces
So you have a line:
var line = "hello world my name is bob";
And you don't want "world" or "is", so you want:
"hello my name bob"
If you split to a list, remove the things you don't want and recombine to a line, you won't have extraneous spaces:
var list = line.Split().ToList();
list.Remove("world");
list.Remove("is");
var result = string.Join(" ", list);
Or if you know the exact index positions of your list items, you can use RemoveAt, but remove them in order from highest index to lowest, because if you e.g. want to remove 1 and 4, removing 1 first will mean that the 4 you wanted to remove is now in index 3.. Example:
var list = line.Split().ToList();
list.RemoveAt(4); //is
list.RemoveAt(1); //world
var result = string.Join(" ", list);
If you're seeking a behavior that is like string.Replace, which removes all occurrences, you can use RemoveAll:
var line = "hello is world is my is name is bob";
var list = line.Split().ToList();
list.RemoveAll(w => w == "is"); //every occurence of "is"
var result = string.Join(" ", list);
You could remove the empty space using TrimStart() method.
Something like this:
string text = "Hello World";
string[] textSplited = text.Split(' ');
string result = text.Replace(textSplited[0], "").TrimStart();
Assuming that you only want to remove the first word and not all repeats of it, a much more efficient way is to use the overload of split that lets you control the maximum number of splits (the argument is the maximum number of results, which is one more than the maximum number of splits):
string[] arguments = line.Split(new[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries); // split only once
User.data = arguments.Skip(1).FirstOrDefault();
arguments[1] does the right thing when there are "more" arguments, but throw IndexOutOfRangeException if the number of words is zero or one. That could be fixed without LINQ by (arguments.Length > 1)? arguments[1]: string.Empty
If you're just removing the first word of a string, you don't need to use Split at all; doing a Substring after you found the space will be more efficient.
var line = ...
var idx = line.IndexOf(' ')+1;
line = line.Substring(idx);
or in recent C# versions
line = line[idx..];
I have the following example strings:
TAR:100
TAR:100|LED:50
TAR:30|LED:30|ASO:40
I need a regex that obtains the numeric values after the colon, which are always in the range 0 to 100 inclusive.
The result after the regex is applied to any of the above strings should be:
for TAR:100 the result should be 100
for TAR:100|LED:50 the result should be the array [100,50]
for TAR:30|LED:30|ASO:40 the result should be the array [30,30,40]
The word before the colon can have any length and both upper and lowercase.
I have tried with the following but it doesn't yield the result I need:
String text = "TAR:100|LED:50";
String pattern = "\\|?([a-zA-Z]{1,}:)";
string[] values= Regex.Split(text, pattern);
The regex should work whether the string is TAR:100 or TAR:100|LED:50 if possible.
You added () which makes the text parts that you want to remove also be returned.
Below is my solution, with a slightly changed regex.
Note that we need to start looping the values at i = 1, which is purely caused by using Split on a string that starts with a split-sequence; it has nothing to do with the Regex itself.
Explanation: if we used a simpler str.Split to split by a separator "#", then "a#b#c" would produce ["a", "b", "c"], whereas "#b#c" would produce ["", "b", "c"]. In general, and by definition: if Split removes N sequences by which the string gets splitted, then the result is N+1 strings. And all the strings that we deal with here are of the form "#b#c", so there is always an empty first result.
Accepting that as a given fact, the results are usable by starting from i = 1:
var pattern = #"\|?[a-zA-Z]+:";
var testCases = new[] { "TAR:100", "TAR:100|LED:50", "TAR:30|LED:30|ASO:40" };
foreach (var text in testCases)
{
string[] values = Regex.Split(text, pattern);
for (var i = 1; i < values.Length; i++)
Console.WriteLine(values[i]);
Console.WriteLine("------------");
}
Output:
100
------------
100
50
------------
30
30
40
------------
Working DotNetFiddle: https://dotnetfiddle.net/i9kH8n
In .NET you can use the Group.Captures and use the same name for 2 capture groups and match the format of the string.
\b[a-zA-Z]+:(?<numbers>[0-9]+)(?:\|[a-zA-Z]+:(?<numbers>[0-9]+))*\b
Regex demo | C# demo
string[] strings = {
"TAR:100",
"TAR:100|LED:50",
"TAR:30|LED:30|ASO:40"
};
string pattern = #"\b[a-zA-Z]+:(?<numbers>[0-9]+)(?:\|[a-zA-Z]+:(?<numbers>[0-9]+))*\b";
foreach (String str in strings)
{
Match match = Regex.Match(str, pattern);
if (match.Success)
{
string[] result = match.Groups["numbers"].Captures.Select(c => c.Value).ToArray();
Console.WriteLine(String.Join(',', result));
}
}
Output
100
100,50
30,30,40
Another option could be making use of the \G anchor and have the value in capture group 1.
\b(?:[a-zA-Z]+:|\G(?!^))([0-9]+)(?:\||$)
Regex demo | C# demo
string[] strings = {
"TAR:100",
"TAR:100|LED:50",
"TAR:30|LED:30|ASO:40"
};
string pattern = #"\b(?:[a-zA-Z]+:|\G(?!^))([0-9]+)(?:\||$)";
foreach (String str in strings)
{
MatchCollection matches = Regex.Matches(str, pattern);
string[] result = matches.Select(m => m.Groups[1].Value).ToArray();
Console.WriteLine(String.Join(',', result));
}
Output
100
100,50
30,30,40
I would like to do something like this:
My string example: "something;123:somethingelse;156:somethingelse2;589:somethingelse3"
I would like to get an array with values extracted from the string example. These values lies between ";" and ":" : 123, 156, 589
I have tried this, but I do not know how to iterate to get all occurrences:
string str = stringExample.Split(';', ':')[1];
string[i] arr = str;
Thank you for helping me.
LINQ is your friend here, something like this would do:
str.Split(';').Select(s => s.Split(':')[0]).Skip(1)
I would work with named groups:
string stringExample = "something;123:somethingelse;156:somethingelse2;589:somethingelse3";
Regex r = new Regex(";(?<digit>[0-9]+):");
foreach (Match item in r.Matches(stringExample))
{
var digit = item.Groups["digit"].Value;
}
You can use a regular expression like this:
Regex r = new Regex(#";(\d+):");
string s = "something;123:somethingelse;156:somethingelse2;589:somethingelse3";
foreach(Match m in r.Matches(s))
Console.WriteLine(m.Groups[1]);
;(\d+): matches one or more digits standing between ; and : and Groups[1] selects the content inside the brackest, ergo the digits.
Output:
123
156
589
To get these strings into an array use:
string[] numberStrings = r.Matches(s).OfType<Match>()
.Select(m => m.Groups[1].Value)
.ToArray();
So you want to extract all 3 numbers, you could use this approach:
string stringExample = "something;123:somethingelse;156:somethingelse2;589:somethingelse3";
string[] allTokens = stringExample.Split(';', ':'); // remove [1] since you want the whole array
string[] allNumbers = allTokens.Where(str => str.All(Char.IsDigit)).ToArray();
Result is:
allNumbers {string[3]} string[]
[0] "123" string
[1] "156" string
[2] "589" string
This sounds like a perfect case for a regular expression.
var sample = "something;123:somethingelse;156:somethingelse2;589:somethingelse3";
var regex = new Regex(#"(?<=;)(\d+)(?=:)");
var matches = regex.Matches(sample);
var array = matches.Cast<Match>().Select(m => m.Value).ToArray();
I want to split a string into 2 strings,
my string looks like:
HAMAN*3 whitespaces*409991
I want to have two strings the first with 'HAMAN' and the second should contain '409991'
PROBLEM: My second string has '09991' instead of '409991' after implementing this code:
string str = "HAMAN 409991 ";
string[] result = Regex.Split(str, #"\s4");
foreach (var item in result)
{
MessageBox.Show(item.ToString());
}
CURRENT SOLUTION with PROBLEM:
Split my original string when I find whitespace followed by the number 4. The character '4' is missing in the second string.
PREFERED SOLUTION:
To split when I find 3 whitespaces followed by the digit 4. And have '4' mentioned in my second string.
Try this
string[] result = Regex.Split(str, #"\s{3,}(?=4)");
Here is the Demo
Positive lookahead is your friend:
Regex.Split(str, #"\s+(?=4)");
Or you could not use Regex:
var str = "HAMAN 409991 ";
var result = str.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
EXAMPLE
Alternative if you need it to start with SPACESPACESPACE4:
var str = new[] {
"HAMAN 409991 ",
"HAMAN 409991",
"HAMAN 509991"
};
foreach (var s in str)
{
var result = s.Trim()
.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries)
.Select(a => a.Trim())
.ToList();
if (result.Count != 2 || !result[1].StartsWith("4"))
continue;
Console.WriteLine("{0}, {1}", result[0], result[1]);
}
That's because you're splitting including the 4. If you want to split by three-consecutive-spaces then you should specify exactly that:
string[] result = Regex.Split(str, #"\s{3}");
I have this data in format
"NEW ITEM:1_BELT:3_JEANS:1_BELT:1_SUIT 3 PCS:1_SHOES:1"
the format is Item1:Item1Qty_Item2:Item2Qty.........ItemN:ItemNQty
I need to separte the the items and their corresponding quantities and form arrays. I did the item part like this..
var allItemsAry = Regex.Replace(myString, "[\\:]+\\d", "").Split('_');
Now allItemsAry is correct like this [NEW ITEM, BELT, JEANS, BELT, SUIT 3 PCS, SHOES]
But I can't figrure out how to get qty, whatever expression I try that 3 from SUIT 3 PCS comes along with that, like these
var allQtyAry = Regex.Replace(dataForPackageConsume, "[^(\\:+\\d)]", "").split(':')
This comes up as :1:3:1:13:1:1 (when replaced). So I can't separate by : to get make it array, as can be seen the forth item is 13, while it should be 1, that 3 is coming from SUIT 3 PCS. I also tried some other variations, but that 3 from SUIT 3 PCS always pops in. How do I just get the quantities of clothes (possible attached with : so I can split them by this and form the array?
UPDATE : If I didn't make it clear before I want the numbers that are exactly preceded by : along with the semicolon.
So, what I want is :1:3:1:1:1:1.
Instead of removing everything except numerals, how about matching only numerals?
For instance:
Regex regex = new Regex(#":\d+");
string result = string.Empty;
foreach (Match match in regex.Matches(input))
result += match.Value;
[^\d:]+|:(?!\d)|(?<!:)\d+
[^\d:]+ will match all non-digit non-:s.
:(?!\d) will match all :s not followed by a digit (negative lookahead).
(?<!:)\d+ will match all digits not preceded by a : (negative lookbehind).
Source
NEW ITEM:1_BELT:3_JEANS:1_BELT:1_SUIT 3 PCS:1_SHOES:1
Regular Expression
[^\d:]+|:(?!\d)|(?<!:)\d+
Results
Match
NEW ITEM
_BELT
_JEANS
_BELT
_SUIT
3
PCS
_SHOES
You want it only numbers like :1:3:1:1:3:1:1 ?
string s = "NEW ITEM:1_BELT:3_JEANS:1_BELT:1_SUIT 3 PCS:1_SHOES:1";
var output = Regex.Replace(s, #"[^0-9]+", "");
StringBuilder sb = new StringBuilder();
foreach (var i in output)
{
sb.Append(":" + i);
}
Console.WriteLine(sb); // :1:3:1:1:3:1:1
Here is a DEMO.
Ok, if every char is digit after : then you can use it like;
string s = "NEW ITEM:1_BELT:3_JEANS:1_BELT:1_SUIT 3 PCS:1_SHOES:1";
var array = s.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
StringBuilder sb = new StringBuilder();
foreach (var item in array)
{
if (Char.IsDigit(item[0]))
{
sb.Append(":" + item[0]);
}
}
Console.WriteLine(sb); //:1:3:1:1:1:1
DEMO.
This will work with one replace:
var allQtyAry = Regex.Replace(dataForPackageConsume, #"[^_:]+:", "").split('_')
Explanation:
[^_:] means match anything that's not a _ or a :
[^_:]+: means match any sequence of at least one character not matching either _ or :, but ending with a :
Since regular expressions are greedy by default (ie they grab as much as possible), matching will start at the beginning of the string or after each _:
NEW ITEM: 1_BELT: 3_JEANS: 1_BELT: 1_SUIT 3 PCS: 1_SHOES: 1
Removing the matched parts (the italic bold bits above) results in:
1_3_1_1_1_1
Splitting by _ results in:
[1, 3, 1, 1, 1, 1]
Try this regex [^:\d+?].*?(?=:), it should do the trick
string[] list = Regex.Replace(test, #"[^:\d+?].*?(?=:)", string.Empty).Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
The regex matches and replaces with an empty string everything preceding the colon : (exclusive) .*?(?=:). It also excludes :# from the match [^:\d+?] thus you end up with :1:3:1:1:1:1 before the split