So I've been trying to figure out how to delete characters after a certain point on each line, for example I have a list like:
dskfokes=dasfn3rewk
dsanfiwen=434efsde
damkw4343=o3rm3i
dmfkim303rk2=0439wefksd
32i32j9esfj=42393jdsf
How would I go about deleting everything on each line after '='?
Use string.IndexOf() to get the index of the char you want to remove, then string.Remove() to do the removing.
string str = "dskfokes=dasfn3rewk";
str = str.Remove(str.IndexOf('='));
One approach is to use LINQ:
var strings = new string[] {
"dskfokes=dasfn3rewk
, "dsanfiwen=434efsde
, "damkw4343=o3rm3i
, "dmfkim303rk2=0439wefksd
, "32i32j9esfj=42393jdsf
};
var res = strings.Select(s => s.Split('=')[0]).ToArray();
This splits each string on =, and drops everything after the first '=' character if it is there.
You may also do it using String.Split() like
string[] allWords = new string[] {
"dskfokes=dasfn3rewk",
"dsanfiwen=434efsde",
"damkw4343=o3rm3i",
"dmfkim303rk2=0439wefksd",
"32i32j9esfj=42393jdsf"
};
foreach(string s in allWords)
{
string[] urstring = s.Split('=');
Console.WriteLine(urstring[0]);
}
I suggest you to use a combination of string handling operations SubString and IndexOf to achieve this, consider the example:
List<string> inputLine = new List<string>(){ "dskfokes=dasfn3rewk",
"dsanfiwen=434efsde",
"damkw4343=o3rm3i",
"dmfkim303rk2=0439wefksd",
"32i32j9esfj=42393jdsf"};
List<string> outputLines = inputLine.Select(x =>
x.IndexOf('=') == -1 ? x :
x.Substring(0, x.IndexOf('='))).ToList();
Note : The IndexOf will return -1 if the specified index was not found, in such cases substring method will throws errors since -1 will not be a valid index. So we have to check for existence of index withing the string before proceeding. you can also try simple foreach as like this:
List<string> outputLines=new List<string>();
int currentCharIndex=-1;
foreach (string line in inputLine)
{
currentCharIndex = line.IndexOf('=');
if(currentCharIndex ==-1)
outputLines.Add(line);
else
outputLines.Add(line.Substring(0,currentCharIndex));
}
Related
I have a text-file with many lines, each line looks like this:
"string string double double" between each value is a space. I'd like to read out the first string and last double of every line and put these two values in a existing list. That is my code so far, but it doesnt really work.
private void bOpen_Click(object sender, RoutedEventArgs e)
{
bool exists = File.Exists(#"C:\Users\p2\Desktop\Liste.txt");
if (exists == true)
{
StringBuilder sb = new StringBuilder();
using (StreamReader sr = new StreamReader(#"C:\Users\p2\Desktop\Liste.txt"))
{
Vgl comp = new Vgl();
comp.name = Abzahlungsdarlehenrechner.zgName;
comp.gErg = Abzahlungsdarlehenrechner.zgErg;
GlobaleDaten.VglDaten.Add(comp);
int i = 0;
string line = File.ReadLines(#"Liste.txt").Skip(0).Take(1).First();
while ((line = sr.ReadLine()) != null)
{
sb.Append((line));
listBox.Items.Add(line);
GlobaleDaten.VglDaten.Add(comp);
i++;
}
}
}
I have already read this, but it didnt help How do I read specific value[...]
You can try Linq:
var source = File
.ReadLines(#"C:\Users\p2\Desktop\Liste.txt")
.Select(line => line.Split(' '))
.Select(items => new Vgl() {
name = items[0],
gErg = double.Parse(items[3])
});
// If you want to add into existing list
GlobaleDaten.VglDaten.AddRange(source);
// If you want to create a new list
//List<Vgl> list = source.ToList();
how about
List<Vgl> Result = File.ReadLines(#"C:\Users\p2\Desktop\Liste.txt")
.Select(x => new Vgl()
{
name = x.Split(' ').First(),
gErg = decimal.Parse(x.Split(' ').Last(), NumberStyles.AllowCurrencySymbol)
})
.ToList();
I would avoid storing money within doulbe values because this could lead to rounding issues. Use decimal instead. Examples here: Is a double really unsuitable for money?
You can use:
string[] splitBySpace = line.Split(' ');
string first = splitBySpace.ElementAt(0);
decimal last = Convert.ToDecimal(splitBySpace.ElementAt(splitBySpace.Length - 1));
Edit : To Handle Currency symbol:
string[] splitBySpace = line.Split(' ');
string pattern = #"[^0-9\.\,]+";
string first = splitBySpace.ElementAt(0);
string last = (new Regex(pattern)).Split(splitBySpace.ElementAt(splitBySpace.Length - 1))
.FirstOrDefault();
decimal lastDecimal;
bool success = decimal.TryParse(last, out lastDecimal);
I agree with #Dmitry and fubo, if you are looking for alternatives, you could try this.
var source = File
.ReadLines(#"C:\Users\p2\Desktop\Liste.txt")
.Select(line =>
{
var splits = line.Split(' '));
return new Vgl()
{
name = splits[0],
gErg = double.Parse(splits[3])
};
}
use string.split using space as the delimiter on line to the string into an array with each value. Then just access the first and last array element. Of course, if you aren't absolutely certain that each line contains exactly 4 values, you may want to inspect the length of the array to ensure there are at least 4 values.
reference on using split:
https://msdn.microsoft.com/en-us/library/ms228388.aspx
Read the whole file as a string.
Split the string in a foreach loop using \r\n as a row separator. Add each row to a list of strings.
Iterate through that list and split again each record in another loop using space as field separator and put them into another list of strings.
Now you have all the four fields containig one row. Now just use First and Last methods to get the first word and the last number.
I want to remove comma separated duplicate string values like :
String str = "2,4,3,12,25,2,4,3,6,2,2,2";
And i want to output like this:
String str1 = "6,2";
please tell how to do this i'll my self but i can't solve this
A wild ride with Linq. Probably there is a better way, but this is the first one I could think of.
string str = "2,4,3,12,25,2,4,3,6,2,2,2";
List<string> uniques = str.Split(',').Reverse().Distinct().Take(2).Reverse().ToList();
string newStr = string.Join(",", uniques);
Console.WriteLine(newStr);
Split the string at the comma to get the sequence
Apply the Reverse op, you get 2 2 2 6 .... 4 2
Apply the Distinct, you get 2,6,3,4,25,12
Take the first 2 elements (2,6)
Reverse them 6,2
Join in a new string with the comma sep.
Pretty basic but works in your case
String str = "2,4,3,12,25,2,4,3,6,2,2,2";
String[] arr = str.Split(',');
String penultimate = "";
String ultimate = "";
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] != ultimate)
{
penultimate = ultimate;
ultimate = arr[i];
}
}
Console.WriteLine("{0},{1}", penultimate, ultimate);
Here is a suggestion:
string item = "";
var lastTwoUnique= str.Split(',') //split the string on ,
//now, take the next element from the array as long as it's
//not equal to the previous element (which we store in item)
.Where((st) => st==item ? false : (item = st) == item) //** see comment below
.Reverse() //reverse collection
.Take(2) //take two (two last)
.Reverse() //reverse back
.ToList(); //make it a list
var answer = string.Join(",", lastTwoUnique);
This solution keeps the data intact, so if you want you could store the unique list, then do many queries on that list. Solutions using Distinct() will, for instance, not keep every occurrence of 2 in the list.
This solution has the intermediate result (after Where) of: 2,4,3,12,25,2,4,3,6,2. While distinct will be:2,4,3,12,25,6
** The line .Where((st) => st==item ? false : (item = st) == item) may seem odd, so let me explain:
Where takes a lambda function that returns true for items that should be taken, and false for the items that should be ignored. So st will become each sub string from the Split.
Now, let's investigate the actual function:
st==item //is this st equal to the previous item?
? false //then return false
: (item = st) == item //if it's not equal, then assign `item` to the current `st`
//and compare that to item and get `true`
You could use the .Distinct() extension method.
String str = "2,4,3,12,25,2,4,3,6,2,2,2";
var oldArray=str.Split(',').Reverse();
var collectionWithDistinctElements = oldArray.Distinct().ToArray();
var reverse=collectionWithDistinctElements.Reverse();
//take two element
var twoElements=reverse.ToList().Take(2);
//last join them
var resultArray=string.Join(",", twoElements);
Another solution, which I've attempted to keep quite simple:
String str = "2,4,3,12,25,2,4,3,6,2,2,2";
var holder = new string[2];
foreach (var x in str.Split(','))
{
if(holder.Last() != x)
{
holder[0] = holder[1];
holder[1] = x;
}
}
var result = string.Join(",", holder);
This will iterate over the comma-separated items, all the time keeping the two last seen distinct items in holder.
String str = "2,4,3,12,25,2,4,3,6,2,2,2";
string str = s1;
var uniques = str.Split(',').Reverse().Distinct().Take(3).Reverse().Take(2).ToList();
string newStr = string.Join(",", uniques.ToArray());
This will give me correct output that is 3,6 thats i want.
Thanks to all the Guys that give me ans.
This will definitely work
string str = "2,4,3,12,25,2,4,3,6,2,2,2";
List<string> uniques = new List<string>()
uniques = str.Split(',').Reverse().Distinct().Take(2).Reverse().ToList();
string newStr = string.Join(",", uniques);
I have problems splitting this Line. I want to get each String between "#VAR;" and "#ENDVAR;". So at the End, there should be a output of:
Variable=Speed;Value=Fast;
Variable=Fabricator;Value=Freescale;Op==;
Later I will separate each Substring, using ";" as a delimiter but that I guess wont be that hard. This is how a line looks like:
#VAR;Variable=Speed;Value=Fast;Op==;#ENDVAR;#VAR;Variable=Fabricator;Value=Freescale;Op==;#ENDVAR;
I tried some split-options, but most of the time I just get an empty string. I also tried a Regex. But either the Regex was wrong or it wasnt suitable to my String. Probably its wrong, at school we learnt Regex different then its used in C#, so I was confused while implementing.
Regex.Match(t, #"/#VAR([a-z=a-z]*)/#ENDVAR")
Edit:
One small question: I am iterating over many lines like the one in the question. I use NoIdeas code on the line to get it in shape. The next step would be to print it as a Text-File. To print an Array I would have to loop over it. But in every iteration, when I get a new line, I overwrite the Array with the current splitted string. I put the Rest of my code in the question, would be nice if someone could help me.
string[] w ;
foreach (EA.Element theObjects in myPackageObject.Elements)
{
theObjects.Type = "Object";
foreach (EA.Element theElements in PackageHW.Elements)
{
if (theObjects.ClassfierID == theElements.ElementID)
{
t = theObjects.RunState;
w = t.Replace("#ENDVAR;", "#VAR;").Replace("#VAR;", ";").Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
foreach (string s in w)
{
tw2.WriteLine(s);
}
}
}
}
The piece with the foreach-loop is wrong pretty sure. I need something to print each splitted t. Thanks in advance.
you can do it without regex using
str.Replace("#ENDVAR;", "#VAR;")
.Split(new string[] { "#VAR;" }, StringSplitOptions.RemoveEmptyEntries);
and if you want to save time you can do:
str.Replace("#ENDVAR;", "#VAR;")
.Replace("#VAR;", ";")
.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
You can use a look ahead assertion here.
#VAR;(.*?)(?=#ENDVAR)
If your string never consists of whitespace between #VAR; and #ENDVAR; you could use the below line, this will not match empty instances of your lines.
#VAR;([^\s]+)(?=#ENDVAR)
See this demo
Answer using raw string manipulation.
IEnumerable<string> StuffFoundInside(string biggerString)
{
var closeDelimeterIndex = 0;
do
{
int openDelimeterIndex = biggerString.IndexOf("#VAR;", startingIndex);
if (openDelimeterIndex != -1)
{
closeDelimeterIndex = biggerString.IndexOf("#ENDVAR;", openDelimeterIndex);
if (closeDelimiterIndex != -1)
{
yield return biggerString.Substring(openDelimeterIndex, closeDelimeterIndex - openDelimiterIndex);
}
}
} while (closeDelimeterIndex != -1);
}
Making a list and adding each item to the list then returning the list might be faster, depending on how the code using this code would work. This allows it to terminate early, but has the coroutine overhead.
Use this regex:
(?i)#VAR;(.+?)#ENDVAR;
Group 1 in each match will be your line content.
(If you don't like regexs)
Code:
var s = "#VAR;Variable=Speed;Value=Fast;Op==;#ENDVAR;#VAR;Variable=Fabricator;Value=Freescale;Op==;#ENDVAR;";
var tokens = s.Split(new String [] {"#ENDVAR;#VAR;"}, StringSplitOptions.None);
foreach (var t in tokens)
{
var st = t.Replace("#VAR;", "").Replace("#ENDVAR;", "");
Console.WriteLine(st);
}
Output:
Variable=Speed;Value=Fast;Op==;
Variable=Fabricator;Value=Freescale;Op==;
Regex.Split works well but yields empty entries that have to be removed as shown here:
string[] result = Regex.Split(input, #"#\w+;")
.Where(s => s != "")
.ToArray();
I tried some split-options, but most of the time I just get an empty string.
In this case the requirements seem to be simpler than you're stating. Simply splitting and using linq will do your whole operation in one statement:
string test = "#VAR;Variable=Speed;Value=Fast;Op==;#ENDVAR;#VAR;Variable=Fabricator;Value=Freescale;Op==;#ENDVAR;";
List<List<string>> strings = (from s in test.Split(new string[]{"#VAR;",";#ENDVAR;"},StringSplitOptions.RemoveEmptyEntries)
let s1 = s.Split(new char[]{';'},StringSplitOptions.RemoveEmptyEntries).ToList<string>()
select (s1)).ToList<List<string>>();
the outpout is:
?strings[0]
Count = 3
[0]: "Variable=Speed"
[1]: "Value=Fast"
[2]: "Op=="
?strings[1]
Count = 3
[0]: "Variable=Fabricator"
[1]: "Value=Freescale"
[2]: "Op=="
To write the data to a file something like this will work:
foreach (List<string> s in strings)
{
System.IO.File.AppendAllLines("textfile1.txt", s);
}
Suppose I am given a following text (in a string array)
engine.STEPCONTROL("00000000","02000001","02000043","02000002","02000007","02000003","02000008","02000004","02000009","02000005","02000010","02000006","02000011");
if("02000001" == 1){
dimlevel = 1;
}
if("02000001" == 2){
dimlevel = 3;
}
I'd like to extract the strings that's in between the quotation mark and put it in a separate string array. For instance, string[] extracted would contain 00000000, 02000001, 02000043....
What is the best approach for this? Should I use regular expression to somehow parse those lines and split it?
Personally I don't think a regular expression is necessary. If you can be sure that the input string is always as described and will not have any escape sequences in it or vary in any other way, you could use something like this:
public static string[] ExtractNumbers(string[] originalCodeLines)
{
List<string> extractedNumbers = new List<string>();
string[] codeLineElements = originalCodeLines[0].Split('"');
foreach (string element in codeLineElements)
{
int result = 0;
if (int.TryParse(element, out result))
{
extractedNumbers.Add(element);
}
}
return extractedNumbers.ToArray();
}
It's not necessarily the most efficient implementation but it's quite short and its easy to see what it does.
that could be
string data = "\"00000000\",\"02000001\",\"02000043\"".Replace("\"", string.Empty);
string[] myArray = data.Split(',');
or in 1 line
string[] data = "\"00000000\",\"02000001\",\"02000043\"".Replace("\"", string.Empty).Split(',');
I have a list of strings of the following pattern: "name\middleName".
What is the nicest way to turn into a list in which all the elements are just "name"?
(i.e split the string and leave only the "name" part)
Thanks,
Li
List<string> originalList = ...
List<string> newList = originalList.Select(s => s.Split('\\')[0]).ToList()
List<string> original = ...
List<string> nameOnly = original.ConvertAll(s => s.Substring(0, s.IndexOf('\\')));
If it's possible that there might not be a \ character in some elements of the original list then you'll need an additional check to avoid exceptions:
List<string> nameOnly = original.ConvertAll(s => {
int i = s.IndexOf('\\');
return (i == -1)
? s
: s.Substring(0, i);
});
//your list of strings in format (name\middleName)
List<string> list;
List<string> newList;
foreach(string item in list)
newList.Add(item.Substring(0, item.IndexOf("\\")));
That would make a copy of your string list into a new one formatted like you wanted.
Tokenize "/" and assign the first string to name variable.
Or just make loop of all those strings in a list and inside a loop do a loop on a string length which puts chars into variable and exits when reaches "/" and then stores it as a name.
Here's a regular expression solution for you that doesn't create a new list.
for(int i = 0; i < list.count; i++)
{
list[i] = Regex.Match(List[i],#"^\w+").value
}