For the following code...
IEnumerable<string> items=searchterms.Trim().Split(Environment.NewLine.ToCharArray());
foreach (var item in items) {
I'm getting an item of length 0 in-between each searchterm item. I've used similar code elsewhere and not run into this, so not sure why it's happenning now. What do I need to add here to get rid of these extra entries? i.e. so that the number of items matches the number of terms in the input. I have a work-around (skip items with length 0), but it's an annoyance that the numbers don't match, and I would like to fix it for displaying progress purposes. i.e. item i+1 of items.count.
P.S. this is in Xamarin Forms on UWP.
thanks,
Donald.
The problem is that you split by a char array of { '\r', '\n' } which means either symbol is regarded as a separator, not the whole sequence of "\r\n", i.e. there is an empty string in "\r\n" in between.
To split by the whole sequence only use a string array of one element
IEnumerable<string> items = searchterms.Trim().Split(new string[] { Environment.NewLine, }, StringSplitOptions.None);
This will not produce an empty item unless there are to consecutive "\r\n" in the string. If you also want to remove empty items in such case you can use the RemoveEmptyEntries string split option.
IEnumerable<string> items = searchterms.Trim().Split(new string[] { Environment.NewLine, }, StringSplitOptions.RemoveEmptyEntries);
Since the newline is composed from 2 characters (on most systems anyway, \r and \n), you may be getting an extra empty string as the string between these characters.
Try this:
IEnumerable<string> items=searchterms.Trim().Split(new string[] {Environment.NewLine}, StringSplitOptions.None);
foreach (var item in items) {
Related
So I'm currently working on a program that reads a large txt file line by line as strings. For a particular section of the file the format is like this:
text1 : text2 : text3 : text4 : text5 : text6
I know how to split the string and find different counts.
What I want to do is check that the text in text5 starts with a certain expression SORT, and then for that line print text3.
foreach (string str in File.ReadLines(#"/filelocation"))
{
if (str.StartsWith("fusedef"))
{
string text3 = str.Split(':')[2];
string text5 = str.Split(':')[4];
if (text5.StartsWith("SORT_"))
{
Console.WriteLine(text3);
}
}
(As far as I know, counting a split string starts at 0 but correct me if I'm wrong, only started c# a few weeks ago. Thanks!)
You need to remove any char that could potentially confuse the StartsWith. In particular those empty spaces before the string start.
There is an overload of string.Split that allows you to set more than one char to split on and then remove eventually empty strings returned by this split
string[] blocks = str.Split(new char[] {':', ' '}, StringSplitOptions.RemoveEmptyEntries);
if (blocks[4].StartsWith("SORT_"))
{
Console.WriteLine(blocks[2]);
}
In alternative you could Trim the blocks strings
string[] blocks = str.Split(':');
if (blocks[4].Trim().StartsWith("SORT_"))
{
Console.WriteLine(blocks[2]);
}
Splitting the string will output a string array. To really make use of C# and how simple you can make things why not try operating on your string using a List?
If you know the order that items will appear in you can just call up a string from any position in your list.
foreach (string str in File.ReadLines(#"/filelocation")) {
if (str.StartsWith("fusedef")) {
List<string> list = str.Split(':').ToList();
if (list[5].StartsWith("SORT_"))
Console.WriteLine(list[3]);
}
}
Hope this helps!
Edit: you may want to remove the leading and trailing spaces from your separator. or split your string using ' : ' rather than ':'.
I am working on an application where I have multiple ID in a string that I passed from my view separated by a ';'.
So this is what it looks like "P171;P172".
if (ModelState.IsValid)
{
hiddenIDnumber= hiddenIDnumber.Trim();
List<string> listStrLineElements = hiddenIDnumber.Split(';').ToList();
foreach (string str in listStrLineElements)
The problem is, when I split my hiddenIDnumber, even if I have two numbers, I get a count of 3 and "" is returned (which I believe is an empty space).
When I use a breakpoint i get "P171","P172" AND "".
This is causing my program to fail because of my FK constraints.
Is there a way to "overcome this and somehow "trim" the space out?
Use another overload of string.Split whih allows you to ignore empty entries. For example:
List<string> listStrLineElements = hiddenIDnumber
.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
.ToList();
I would say that one way to do this would be to use String Split Options. With String.Split there is an overload that takes two arguments, i.e. it would be like
myString.Split(new [] {';'}, StringSplitOptions.RemoveEmptyEntries);
This should prevent any entries in your array that would only be an empty string.
var listStrLineElements = hiddenIDnumber.Split(new char[]{';'}, StringSplitOptions.RemoveEmptyEntries);
Use the parameter StringSplitOptions.RemoveEmptyEntries to automatically remove empty entries from the result list.
You can try:
IList<string> listStrLineElements = hiddenIDnumber.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
I prefer this over new [] { ';' } for readability, and return it to an interface (IList<string>).
You will end up with the number of ;s plus one when you split. Since your comment mentions you have 2 ;s, you will get 3 in your list: before the first semicolon, between the first and the second, and after the second. You are not getting an empty space, you are getting a string.Empty because you have nothing after the last ;
if (ModelState.IsValid)
{
hiddenIDnumber= hiddenIDnumber.Trim(";");
List<string> listStrLineElements = hiddenIDnumber.Split(';').ToList();
foreach (string str in listStrLineElements)
This way you get rid of the ; at the end before you split, and you don't get an empty string back.
I have a string which contains value like.
90 524 000 1234567890 2207 1926 00:34 02:40 S
Now i have broken this string into string Array based on white-space.Now i want to create one more string array into such a way so that all the white-space gets removed and it contains only real value.
Also i want to get the position of the string array element from the original string array based on the selection from the new string array formed by removing white space.
Please help me.
You can use StringSplitOptions.RemoveEmptyEntries via String.Split.
var values = input.Split(new [] {' '}, StringSplitOptions.RemoveEmptyEntries);
StringSplitOptions.RemoveEmptyEntries: The return value does not include array elements that contain an empty string
When the Split method encounters two consecutive white-space it will return an empty string.Using StringSplitOptions.RemoveEmptyEntries will remove the empty strings and give you only the values you want.
You can also achieve this using LINQ
var values = input.Split().Where(x => x != string.Empty).ToArray();
Edit: If I understand you correctly you want the positions of the values in your old array. If so you can do this by creating a dictionary where the keys are the actual values and the values are indexes:
var oldValues = input.Split(' ');
var values = input.Split().Where(x => x != string.Empty).ToArray();
var indexes = values.ToDictionary(x => x, x => Array.IndexOf(oldValues, x));
Then indexes["1234567890"] will give you the position of 1234567890 in the first array.
You can use StringSplitOptions.RemoveEmptyEntries:
string[] arr = str.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
Note that i've also added tab character as delimiter. There are other white-space characters like the line separator character, add as desired. Full list here.
string s = "90 524 000 1234567890 2207 1926 00:34 02:40 S ";
s.Split(' ').Where(x=>!String.IsNullOrWhiteSpace(x))
I have the following expression:
"<p>What ?</p>\n<pre>Starting Mini</pre>"
When I perform a split as follows:
var split = content
.Split(new[] { "<pre>", "</pre>" }, StringSplitOptions.None);
Then it gives me three entries:
"<p>What ?</p>\n"
"Starting Mini"
""
Why does it give an empty line as the third entry and how can I avoid this?
The "why" is simply: the input (if you don't remove empty entries) will always "split" at any occurrence of the separator(s), so if the separator(s) appear n times in the string, then the array will be n+1 long. In particular, this essentially lets you know where they occurred in the original string (although when using multiple separators, it doesn't let you know which appeared where).
For example, with a simple example (csv without any escaping etc):
string[] arr = input.Split(','); // even if something like "a,b,c,d,"
// which allows...
int numberOfCommas = arr.Length - 1;
string original = string.Join(",", arr);
The fix is, as already mentioned, to use RemoveEmptyEntries.
Use StringSplitOptions.RemoveEmptyEntries instead to remove empty string in list
var split = content
.Split(new[] { "<pre>", "</pre>" }, StringSplitOptions.RemoveEmptyEntries);
You get this behaviour as specified from Microsoft:
"Adjacent delimiters yield an array element that contains an empty string ("")."
So since you have the last pre you get the last empty array element
Mailou, instead of giving 'StringSplitOptions.None' try 'StringSplitOptions.RemoveEmptyEntries'. It removes the the empty lines.
The reason you are getting this behaviour is that your one of the delimeter </pre> happens to exist at the end of the string.
You may see: string.Split - MSDN
...a delimiter is found at the beginning or end of this instance, the
corresponding array element contains Empty
To overcome this:
Use StringSplitOptions.RemoveEmptyEntries instead of StringSplitOptions.None
StringSplitOptions.RemoveEmptyEntries - MSDN
The return value does not include array elements that contain an empty
string
var split = content
.Split(new[] { "<pre>", "</pre>" }, StringSplitOptions.RemoveEmptyEntries);
You also need to specify the
StringSplitOptions.RemoveEmptyEntries enumerator.
The split string[] values not include any empty string by using StringSplitOptions.RemoveEmptyEntries
var split = content
.Split(new[] { "<pre>", "</pre>" }, StringSplitOptions.RemoveEmptyEntries);
Reference: StringSplitOptions Enumeration
You are getting empty line due to
</pre>
You are instructing split function to split by <pre> and </pre>
As result with <pre> you are getting
<p>What ?</p>\n
Starting Mini</pre>
And next result is with </pre> is
<p>What ?</p>\n
Starting Mini
...
I've come across this several times in the past and have finally decided to find out why.
StringSplitOptions.RemoveEmptyEntries would suggest that it removes empty entries.
So why does this test fail?
var tags = "One, Two, , Three, Foo Bar, , Day , ";
var tagsSplit = tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => s.Trim());
tagsSplit.ShouldEqual(new string[] {
"One",
"Two",
"Three",
"Foo Bar",
"Day"
});
The result:
Values differ at index [2]
Expected string length 5 but was 0. Strings differ at index 0.
Expected: "Three"
But was: <string.Empty>
So it fails because instead of "Three", we have an empty string – exactly what StringSplitOptions.RemoveEmptyEntries should prevent.
Most likely because you change the string after the split. You trim the values after splitting them, RemoveEmptyEntries doesn't consider the string " " empty.
The following would achieve what you want, basically creating your own strip empty elements:
var tagsSplit = tags.Split(',').
Select(tag => tag.Trim()).
Where( tag => !string.IsNullOrEmpty(tag));
Adjacent delimiters yield an array element that contains an empty
string (""). The values of the StringSplitOptions enumeration specify
whether an array element that contains an empty string is included in
the returned array.
" " by definition is not empty (it is actually whitespace), so it is not removed from resulting array.
If you use .net framework 4, you could work around that by using string.IsNullOrWhitespace method
var tagsSplit = tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Where(x => !string.IsNullOrWhiteSpace(x))
.Select(s => s.Trim());
RemoveEmptyEntries do not means space.
Your input string include many "space". You should notice that "space" is not empty. In computer, space is a special ASCII code. so the code:
var tagsSplit = tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => s.Trim());
means:
Split the input by ',' and remove empty entry, not include space. So
you got an array with some space elements.
Then you do trim for each of elements. The space elements become to empty.
That's why you got it.
In .NET 5, they added StringSplitOptions.TrimEntries.
Since StringSplitOptions has the [System.Flags] attribute, it means you can write
var splitResult = tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
When both RemoveEmptyEntries and TrimEntries are specified, it removes both empty values and values which only contain whitespace, whilst trimming all the remaining values.
Try
var tagsSplit = tags.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
This will spit by comma and space, and eliminate empty strings.
I've searched also for a clean way to exclude whitespace-entries during a Split, but since all options seemed like some kind of workarounds, I've chosen to exclude them when looping over the array.
string[] tagsSplit = tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string tag in tagsSplit.Where(t => !string.IsNullOrWhiteSpace(t))) { }
I think this looks cleaner and - as a bonus - .Split(...).ToArray() may be ommited.
Of course, it is an option only when you may loop just after split and do not have to store entries for later use.
As this is a very common need, I went ahead and wrapped the most popular answer in a string extension method:
public static IEnumerable<string> Split_RemoveWhiteTokens(this string s, params char[] separator)
{
return s.Split(separator).
Select(tag => tag.Trim()).
Where(tag => !string.IsNullOrEmpty(tag));
}
To split on ',' as the other examples, use like this:
var result = yourString.Split_RemoveWhiteTokens(',')
Note that the return type is IEnumerable, so you can do additional LINQ queries directly on the return result. Call .ToList() if you want to cast the result to a list.
By EmptyEntries it means a case where two delimiters are directly next to each other with nothing in between. Without using this option, it will print a blank line to represent this delimitation. If you use the "RemoveEmptyEntries" option it will not show the delimitation unless there is actually something between the delimiters. A blank space counts as something between the delimiters. If you tried:
One, Two,, Three,
You should find that RemoveEmptyEntries eliminates the delimitation between the two commas and goes straight from Two to Three.
var tagsSplit = tags.Split(',')
.Where(str => str != String.IsNullOrWhiteSpace(str))
.Select(s => s.Trim());