How to use Linq to Split a String on newlines and space? - c#

I have a string:
string data =
"item1 actived
item2 none
item special I none
item special II actived"
you can see 4 rows in the data.
I need to split a string into a List item as below:
item[0]={Name=item1, Status=actived}
item[1]={Name=item2, Status=none}
item[2]={Name=item Special I, Status=none}
item[3]={Name=item Special II, Status=actived}
I'm tried:
var s = SplitReturn(data);
public string[] SplitReturn(string name)
{
return name.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
}
How do I can Split space in my string and then convert to List?

string data =
#"item1 actived
item2 none
item special I none
item special II actived";
var result = data.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
.Select(item => {
int lastSpace = item.LastIndexOf(' ');
return new
{
Name = item.Substring(0, lastSpace).Trim(),
Status = item.Substring(lastSpace, item.Length - lastSpace).Trim()
}; }).ToList();

Related

Read specific column in text file using C#

I have a column based txt file. How can I read any specific column programmatically?
So far I came up with this solution where it reads the specified column index for example: firstValue[0] will read all the (1) in the text file.
If I write it like this then I'll be able to read the first three index fine, but there has to be a cleaner approach.
Console.WriteLine(string.Join("", firstValue[0], firstValue1, firstValue[2], firstValue[3]));
If there was a way I could count the columns in the text file than pick the index of the column I want to read; that would be ideal.
I would like to read:
121
122
123
124
I've searched online for a similar problem, but they didn't quite have what I wanted.
string[] lines = File.ReadAllLines(YourFile);
foreach (var line in lines)
{
var firstValue = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0];
Console.WriteLine(firstValue[0]);
//Console.WriteLine(string.Join("", firstValue[0], firstValue[1], firstValue[2], firstValue[3]));
}
Console.ReadKey();
You can try this one:
public static List<string> GetColumnValues(string[] lines, int columnNumber)
{
var result = new List<string>();
Regex regex = new Regex("[ ]{2,}", RegexOptions.None);
foreach (var line in lines)
{
var cleanedLine = regex.Replace(line, " ");
var columns = line.Split(" ", StringSplitOptions.RemoveEmptyEntries);
result.Add(columns[columnNumber-1]);
}
return result;
}
Additional checks should be added, but you can get an idea.
The problem was, splitting it like like this:
var firstValue = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
firstValue would equal a concatenated string something like this 121 20412 010 in the foreach loop
So then I tried another approach which was:
var firstValue = line.Split(new string[] { "\t" }, StringSplitOptions.RemoveEmptyEntries);
Which indexed the columns, so I can choose which column I want the data to come from.
foreach (var line in lines)
{
var firstValue = line.Split(new string[] { "\t" }, StringSplitOptions.RemoveEmptyEntries);
Console.WriteLine(firstValue[2]);
}
Output:
010
020
030
040

Get specific data from a line of text

I need to extract the following data (in bold) from the text line below and put it into a data grid;
PERS tooldata t_rrt_ja03579:=[TRUE,[[-39.643,-0.001,1025.49],[0.382684,-0.000130001,-0.923889,0.000120001]],[200.9,[-88.1,-12.6,359.7],[1,0,0,0],29.347,50.927,18.261]];
This line is read from a file. I have managed to trim the line so it gets rid of the "PERS tooldata" and whitespaces and it leaves me with the tool name. I have it bound to data in a datagrid elsewhere in the code which is step 1 complete.
My question is how can I extract the values in bold individually and place them in to double data declarations? The first block of values (-39.643,-0.001,1025.49) is a X,Y,Z co-ordinate value and the second (0.382684,-0.000130001,-0.923889,0.000120001) are Q1,Q2,Q3,Q4.
Below is how i done the name
private void AutoFillToolData(object sender, RoutedEventArgs e)
{
// Gives user option to auto populate datagrid
var AutoFillToolResult = MessageBox.Show("Do you want to auto populate fields?", "Tool Data", MessageBoxButton.YesNo);
if (AutoFillToolResult == MessageBoxResult.Yes)
{
// User directs application to the specified file
System.Windows.Forms.FolderBrowserDialog folderBrowser = new System.Windows.Forms.FolderBrowserDialog();
if (folderBrowser.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
// Application looks for specific file and removes unwanted data
string robotBackupPath = folderBrowser.SelectedPath;
string allDataPath = robotBackupPath + #"\RAPID\TASK1\SYSMOD\ALL_DATA.sys";
string[] tLines = File.ReadAllLines(allDataPath);
List<string> toolDataLines = new List<string>();
foreach (string tLine in tLines)
{
if (tLine.Contains("PERS tooldata") && !tLine.StartsWith("!"))
{
if (tLine.Contains("tToolChanger")) continue;
if (tLine.Contains("tPointer")) continue;
if (tLine.Contains("tHome")) continue;
toolDataLines.Add(tLine);
}
}
foreach (string line in toolDataLines)
{
// Gets the name of the tool
ToolData toolData = GetToolNameFromLine(line);
// Puts the tool name in the DataGrid
TCPData.Add(toolData);
}
}
}
}
private ToolData GetToolNameFromLine(string line)
{
// Removes white space at the beggining of line in txt file
ToolData tooldata = new ToolData();
string[] spaceSplit = line.Trim().Split(' ');
string values = spaceSplit[2];
// Gets Tool Name
int colonLocation = values.IndexOf(":");
tooldata.ToolName = values.Substring(0, colonLocation);
return tooldata;
}
If all the samples you'll have follow the same pattern, extracting those values does not seem difficult:
//First we get all the string after the :=
string tooldata = line.Substring(data.IndexOf(":=") + 2) ;
//Split the string by [
string[] tooldataArray = tooldata.Split(new char[] { '[' }, StringSplitOptions.RemoveEmptyEntries);
//the second and the third strings are what we are interested in
string xyzValue = tooldataArray[1].Replace(']' ,' ');
string Q1234value = tooldataArray[2].Replace(']', ' ');
If after this you want to get the individual parameters, just splitting by , would do.
Edit
This would extract all the values you want to arrays of double:
string tooldata = data.Substring(data.IndexOf(":=") + 2) ;
string[] tooldataArray = tooldata.Split(new char[] { '[' }, StringSplitOptions.RemoveEmptyEntries);
double[] xyzValue = tooldataArray[1].Replace(']' ,' ')
.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => double.Parse(s, CultureInfo.InvariantCulture))
.ToArray();
double[] Q1234value = tooldataArray[2].Replace(']', ' ')
.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => double.Parse(s, CultureInfo.InvariantCulture))
.ToArray();

string and arrays manipulation c#

Here is the code and it is working fine for a single input string
string[] stop_word = new string[]
{
"please",
"try",
"something",
"asking",
"-",
"(", ")",
"/",
".",
"was",
"the"
};
string str = "Please try something (by) yourself. -befor/e asking";
foreach (string word in stop_word)
{
str = str.ToLower().Replace(word, "").Trim();
}
and the output is by yourself before
and now I want to have
string str[] = new string[]
{
"Please try something-by yourself. before (CAD) asking/",
"cover, was adopted. The accuracy (of) the- change map was"
};
and also may be the number of strings is greater than 2 then how to alter this above code to display the str array or store in a text file or database.
Please help with acknowledgements. Thanks
The code for single string need to be put inside a loop for string array
List<string> result = new List<string>();
for(int i =0; i<str.Length; i++)
{
foreach (string word in stop_word)
{
str[i] = str[i].ToLower().Replace(word, "").Trim();
str[i] = Regex.Replace(str[i], #"\s+", " ");
}
result.Add(str[i]);
}
foreach(string r in result)
{
//this is to printout the result
Console.WriteLine(r);
}
You can try it here: https://dotnetfiddle.net/wg83gM
EDIT:
Use regex to replace multiple spaces with one single space
Here is an easy to understand way to do it:
List<string> list = new List<string>();
foreach (string text in str)//loops through your str array
{
string newText =text;
foreach (string word in stop_word) //loops through your word array
{
newText = newText.ToLower().Replace(word, "").Trim();
}
list.Add(newText); //store the results in a list
}
Here is a working Demo
Does this work as you expect?
var results =
str
.Select(x => stop_word.Aggregate(x, (a, y) => a.ToLower().Replace(y, "").Trim()))
.ToArray();
I used this input:
string[] str = new string[]
{
"Please try something-by yourself. before (CAD) asking/",
"cover, was adopted. The accuracy (of) the- change map was"
};
string[] stop_word = new string[]
{
"please", "try", "something", "asking", "-", "(", ")", "/", ".", "was", "the"
};
I got this output:
by yourself before cad
cover, adopted accuracy of change map
You can use Select() for this.
var results = str.Select(x => {
foreach (string word in stop_word)
{
x = x.ToLower().Replace(word, "").Trim();
}
return x;
}).ToList(); // You can use ToArray() if you wish too.
...
foreach(string result in results)
{
Console.WriteLine(result);
}
Result:
by yourself before cad
cover, adopted accuracy of change map

how to split a string TWICE

I've been trying to split a string twice but I keep getting the error "Index was outside the bounds of the array".
This is the string I intend to split:
"a*b*c*d*e^1*2*3*4*5^e*f*g*h*i^"
such that I use the "^" as a delimiter in the first array separation so that each set will look as follows after the first result
a*b*c*d*e 1*2*3*4*5 e*f*g*h*i
Then thereafter perform another split operation on this set with * as the separator so that the results, for example from the first set is a b c d e
This is the C# code:
words = "a*b*c*d*e^1*2*3*4*5^e*f*g*h*i^";
char[] del = { '^' };
string[] splitResult = words.Split(del);
foreach (string w in splitResult)
{
char[] separator = { '*' };
string[] splitR = w.Split(separator);
foreach (string e in splitR)
{
string first = splitR[0];
string second = splitR[1];
string third = splitR[2];
string fourth = splitR[3];
string fifth = splitR[4];
}
}
To remove the last part where there is no result, how about
In C#
string str = "a*b*c*d*e^1*2*3*4*5^e*f*g*h*i^";
var result = str.Split(new char[] { '^' }, StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Split('*')).ToArray();
In VB.Net
Dim str As String = "a*b*c*d*e^1*2*3*4*5^e*f*g*h*i^"
Dim result = str.Split(New Char() {"^"}, StringSplitOptions.RemoveEmptyEntries)
.Select(Function(x) x.Split("*")).ToArray()
You can do this with Linq:
IEnumerable<IEnumerable<string>> strings = words
.Split(new char[] { '^' }, StringSplitOptions.RemoveEmptyEntries)
.Select(w => w.Split('*'));
or if you prefer to work exclusively with arrays
string[][] strings = words
.Split(new char[] { '^' }, StringSplitOptions.RemoveEmptyEntries)
.Select(w => w.Split('*').ToArray())
.ToArray();
string words= "a*b*c*d*e^1*2*3*4*5^e*f*g*h*i^";
string[] reslts = words.Split(new char[] { '*', '^' }, StringSplitOptions.RemoveEmptyEntries);
You have a terminating separator, So the final string is empty.
If (w != null) {
string[] splitR = w.Split(separator);
If splitR.lenght > 4)
{
string first = splitR[0];
string second = splitR[1];
string third = splitR[2];
string fourth = splitR[3];
string fifth = splitR[4];
}
}
Try this:
string words = "a*b*c*d*e^1*2*3*4*5^e*f*g*h*i^";
char[] del = { '^' };
string[] splitResult = words.Split(del,StringSplitOptions.RemoveEmptyEntries);
foreach (string w in splitResult)
{
char[] separator = { '*' };
string[] splitR = w.Split(separator);
if(splitR.Length==5)
{
string first = splitR[0];
string second = splitR[1];
string third = splitR[2];
string fourth = splitR[3];
string fifth = splitR[4];
Console.WriteLine("{0},{1},{2},{3},{4}", first, second, third, fourth, fifth);
}
}
You are getting exception Index was outside the bounds of the array because in the last loop, it is getting only one item, I suggest you to check for five items:
words = "a*b*c*d*e^1*2*3*4*5^e*f*g*h*i^";
char[] del = { '^' };
string[] splitResult = words.Split(del);
foreach (string w in splitResult)
{
char[] separator = { '*' };
string[] splitR = w.Split(separator);
if (splitR.Length>=5)
{
foreach (string e in splitR)
{
string first = splitR[0];
string second = splitR[1];
string third = splitR[2];
string fourth = splitR[3];
string fifth = splitR[4];
}
}
}
One line does it all
var f = words.Split(new char[] { '^' }, StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Split(new char[] { '*' }).ToArray())
.ToArray();
Your second loop does 5 times same thing (you don't use e).
The exception you got is because a last empty string was included resulting in an empty array that gave the index out of range exception in the inner loop.

How to split this string to array?

I have string (from a file):
[\x22thanh\x22,
[[\x22thanh\\u003Cb\\u003E nien\\u003C\\/b\\u003E\x22,0,[]],
[\x22thanh\\u003Cb\\u003E ca\\u003C\\/b\\u003E\x22,0,[]],
[\x22thanh\\u003Cb\\u003E nhan\\u003C\\/b\\u003E\x22,0,[]],
[\x22thanh\\u003Cb\\u003E thao\\u003C\\/b\\u003E\x22,0,[]]
]
I saved this string to a variable name "s". I want split all strings betwen "[\x22" and "\x22," then save to an array named "s2". How I can do this? Thank you very much!
You can do as following :
var myArray = myString.Split("[\x22");
Do you want to remove the last characters aswell?
string[] s2 = s.Split(new string[] {#"[\x22", #"\x22"},
StringSplitOptions.RemoveEmptyEntries);
string s = #"[\x22thanh\x22,
[[\x22thanh\\u003Cb\\u003E nien\\u003C\\/b\\u003E\x22,0,[]],
[\x22thanh\\u003Cb\\u003E ca\\u003C\\/b\\u003E\x22,0,[]],
[\x22thanh\\u003Cb\\u003E nhan\\u003C\\/b\\u003E\x22,0,[]],
[\x22thanh\\u003Cb\\u003E thao\\u003C\\/b\\u003E\x22,0,[]]
]";
string start = #"[\x22";
string end = #"\x22";
int pos = -1;
List<string> list = new List<string>();
while ((pos = s.IndexOf(start)) > -1)
{
s = s.Substring(pos + start.Length);
if ((pos = s.IndexOf(end)) > -1)
{
list.Add(s.Substring(0, pos));
s = s.Substring(pos + end.Length);
}
else
break;
}
string[] s2 = list.ToArray();
EDIT
Same result using Split:
string[] s2 = s.Split(new string[] { #"[\x22" },
StringSplitOptions.RemoveEmptyEntries)
.Select(i => i.Substring(0, i.IndexOf(#"\x22")))
.ToArray();
You can find the position of first \x22 and next \x22 string. Next, you should copy the text beetween that position. You can get position using IndexOf method.

Categories

Resources