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.
Related
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();
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();
I have code that finds largest word that starts with a capital letter. But I need that word to add a separator and space. Any ideas how I should do it properly?
char[] skyrikliai = { ' ', '.', ',', '!', '?', ':', ';', '(', ')', '\t' };
string eilute = "Arvydas (g. 1964 m. gruodzio 19 d. Kaune)– Lietuvos, krepsininkas, olimpinis ir pasaulio cempionas, nuo 2011 m. spalio 24 d.";
static string Ilgiausias(string eilute, char[] skyrikliai)
{
string[] parts = eilute.Split(skyrikliai,
StringSplitOptions.RemoveEmptyEntries);
string ilgiaus = "";
foreach (string zodis in parts)
if ((zodis.Length > ilgiaus.Length) && (zodis[0].ToString() == zodis[0].ToString().ToUpper()))
ilgiaus = zodis;
return ilgiaus;
}
It should find word Lietuvos and add , and space
Result should be "Lietuvos, "
I would use LINQ for that:
var ilgiaus = parts.Where(s => s[0].IsUpper())
.OrderByDescending(s => s.Length)
.FirstOrDefault();
if(ilgiaus != null) {
return ilgiaus + ", ";
}
Also you can use regex and linq. You dont need to split by many characters.
Regex regex = new Regex(#"[A-Z]\w*");
string str = "Arvydas (g. 1964 m. gruodzio 19 d. Kaune)– Lietuvos, krepsininkas, olimpinis ir pasaulio cempionas, nuo 2011 m. spalio 24 d.";
string longest = regex.Matches(str).Cast<Match>().Select(match => match.Value).MaxBy(val => val.Length);
if you dont want to use MoreLinq, instead of MaxBy(val => val.Length) you can do OrderByDescending(x => x.Length).First()
There are probably more ingenious and elegant ways, but the following pseudocode should work:
List<String> listOfStrings = new List<String>();
// add some strings to the generic list
listOfStrings.Add("bla");
listOfStrings.Add("foo");
listOfStrings.Add("bar");
listOfStrings.Add("Rompecabeza");
listOfStrings.Add("Rumpelstiltskin");
. . .
String longestWorld = String.Empty;
. . .
longestWord = GetLongestCapitalizedWord(listOfStrings);
. . .
private String GetLongestCapitalizedWord(List<String> listOfStrings)
{
foreach (string s in listofstrings)
{
if ((IsCapitalized(s) && (s.Len > longestWord.Len)))
{
longestWord = s;
}
}
}
private bool IsCapitalized(String s)
{
return // true or false
}
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.
I have the following strings in a text file "test"
Table Name.type
Market Drinks.tea
I wana split the strings so that I get the following output
ObjectName = Table AttributeName = Name Attribute Type =type
ObjectName = Market AttributeName = Drinks Attribute Type =tea
here is my code
string[] lines = File.ReadAllLines(#"d:\test.txt");
int i = 0;
var items = from line in lines
where i++ != 0
select new{
objectName = line.Split(new char[] {' '})[0],
attrName = line.Split(new char[]{'.'})[1],
attrType = line.Split(new char[] { ' ' })[2]
};
foreach (var item in items)
{
Console.WriteLine("ObjectName = {0}, AttributeName = {1}, Attribute Type = {2}",
item.objectName, item.attrName, item.attrType);
}
I'm getting an out of boundaries exception.
PS: there are no spaces at the end of the strings in the text file I just wanted to test a character!
You don't need the new char[] { ... } surrounding because String.Split() uses params
To fix the index-out-of-bounds, the last part of the select should become:
attrType = line.Split(' ', '.' )[2]
Edit
And thanks to #Kobi, a let will let you do the Split just once, a great improvement when you have many rows and/or columns.
var items = from line in lines
where i++ != 0
let words = line.Split(' ', '.')
select new
{
objectName = words[0],
attrName = words[1],
attrType = words[2]
};
Old answer
You can use the same Split for all 3 parts, making it a little easier to read:
select new{
objectName = line.Split(' ', '.' )[0],
attrName = line.Split(' ', '.' )[1],
attrType = line.Split(' ', '.' )[2]
};
Use regular expressions which is more robust:
static void Main()
{
const string PATTERN = #"^([\w]+)\s+([\w]+)\.(\w+)";
const string TEXT = "Table Name.type\r\nMarket Drinks.tea";
foreach (Match match in Regex.Matches(TEXT, PATTERN, RegexOptions.Multiline))
{
Console.WriteLine("ObjectName = {0} AttributeName = {1} Attribute Type ={2}",
match.Groups[1].Value, match.Groups[2].Value, match.Groups[3].Value);
}
}
Outputs:
ObjectName = Table AttributeName = Name Attribute Type =type
ObjectName = Market AttributeName = Drinks Attribute Type =tea
On the splitting part, you should do it like this (provided you are sure your input is in the correct format):
attrName = line.Split(' ')[1].Split('.')[0],
attrType = line.Split(' ')[1].Split('.')[1]
The out of bounds is on this line - attrType = line.Split(new char[] { ' ' })[2]
your attrType should be = line.Split(new char[] { '.' } )[1];
attrName should be = line.Split(new char[] {' '})[1].Split(new char[] {'.'})[0]
As Henk Holterman has said, you dont need to use new char[] inside split so your lines would be -
attrType = line.Split('.')[1];
attrName = line.Split(' ')[1].Split('.')[0];
thx to the replies here is the right answer for the desired output
objectName = line.Split(' ')[0],
attrName = line.Split(' ')[1].Split('.')[0],
attrType = line.Split('.')[1]
if you want to do in this way just use Regex its more flexible
const string pattern = #"(?<objectName>\w+)\s(?<attrName>\w+)\.(?<attrType>\w+)";
string[] lines = File.ReadAllLines(#"e:\a.txt");
var items = from line in lines
select new
{
objectName = Regex.Match(line, pattern).Groups["objectName"].Value,
attrName = Regex.Match(line, pattern).Groups["attrName"].Value,
attrType = Regex.Match(line, pattern).Groups["attrType"].Value
};
foreach (var item in items.ToList())
{
Console.WriteLine("ObjectName = {0}, AttributeName = {1}, Attribute Type = {2}",
item.objectName, item.attrName, item.attrType);
}