I have a string that I am trying to parse the values from. It is in this format "43,56,12,ddl=345".
I am trying to store the ddl value (345) in a separate variable, then the other numbers in a list.
List<int> nums = new List<int>();
int? ddlValue;
How do I go about this?
You could try parsing the string for ints, and then have special checks for any other values you want to store.
var sNums = "43,56,12,ddl=345";
List<int> nums = new List<int>();
int? ddlValue;
foreach (var t in sNums.Split(',')) {
int u;
if (int.TryParse(t, out u)) {
nums.Add(u);
} else {
ddlValue = t.Split("=")[1];
}
}
You can do:
var sNums = "43,56,12,ddl=345".Split(',');
var ddl = int.Parse(sNums.First(s => s.Contains("ddl")).Replace("ddl=", ""));
var numbers = sNums.Where(s => !s.Contains("ddl")).Select(int.Parse);
*note - this will be slightly less efficient that doing it in a single loop - but more readable IMO.
You can do something like this:
List<int> nums=new List<int>();
int intVariable = 0;
string s = "43,56,12,ddl=345";
string[] split=s.Split(',');
Regex regex = new Regex(#"^\d+$");
foreach(var element in split)
if(regex.IsMatch(element))
nums.Add(Convert.ToInt32(element));
else
{
intVariable = element.Split("=")[1];
}
I mean the simplest way is a split and replace.
string values = "43,56,12,ddl=345";
string[] values1 = values.Split(',');
foreach (var x in values1)
{
list.Add(x);
}
string myvalue = values.Split(',')[3];
myvalue = myvalue.Replace("ddl=","");
this assumes your going to be getting the same format every time. Maybe more information?
EDIT-
If you will not always have 3 numbers then the ddl= then string myvalue = values.Split(',')[3]; will not work. Theres a few easy ways around it like
string myvalue = values.Split(',')[values1.Count() - 1]
Related
My program has about 25 entries, most of them string only. However, some of them are supposed to have digits in them, and I don't need those digits in the output (output should be string only). So, how can I "filter out" integers from strings?
Also, if I have integers, strings AND chars, how could I do it (for example, one ListBox entry is E#2, and should be renamed to E# and then printed as output)?
Assuming that your entries are in a List<string>, you can loop through the list and then through each character of each entry, then check if it is a number and remove it. Something like this:
List<string> list = new List<string>{ "abc123", "xxx111", "yyy222" };
for (int i = 0; i < list.Count; i++) {
var no_numbers = "";
foreach (char c in list[i]) {
if (!Char.IsDigit(c))
no_numbers += c;
}
list[i] = no_numbers;
}
This only removes digits as it seems you wanted from your question. If you want to remove all other characters except letters, you can change the logic a bit and use Char.IsLetter() instead of Char.IsDigit().
You can remove all numbers from a strings with this LINQ solution:
string numbers = "Ho5w ar7e y9ou3?";
string noNumbers = new string(numbers.Where(c => !char.IsDigit(c)).ToArray());
noNumbers = "How are you?"
But you can also remove all numbers from a string by using a foreach loop :
string numbers = "Ho5w ar7e y9ou3?";
List<char> noNumList = new List<char>();
foreach (var c in numbers)
{
if (!char.IsDigit(c))
noNumList.Add(c);
}
string noNumbers = string.Join("", noNumList);
If you want to remove all numbers from strings inside a collection :
List<string> myList = new List<string>() {
"Ho5w ar7e y9ou3?",
"W9he7re a3re y4ou go6ing?",
"He2ll4o!"
};
List<char> noNumList = new List<char>();
for (int i = 0; i < myList.Count; i++)
{
foreach (var c in myList[i])
{
if(!char.IsDigit(c))
noNumList.Add(c);
}
myList[i] = string.Join("", noNumList);
noNumList.Clear();
}
myList Output :
"How are you?"
"Where are you going?"
"Hello!"
I don't know exactly what is your scenario, but given a string, you can loop through its characters, and if it's a number, discard it from output.
Maybe this is what you're looking for:
string entry = "E#2";
char[] output = new char[entry.Length];
for(int i = 0, j =0; i < entry.Length ; i++)
{
if(!Char.IsDigit(entry[i]))
{
output[j] = entry[i];
j++;
}
}
Console.WriteLine(output);
I've tried to give you a simple solution with one loop and two index variables, avoiding string concatenations that can make performance lacks.
See this example working at C# Online Compiler
If i am not wrong,maybe this is how your list looks ?
ABCD123
EFGH456
And your expected output is :
ABCD
EFGH
Is that correct?If so,assuming that it's a List<string>,then you can use the below code :
list<string> mylist = new list<string>;
foreach(string item in mylist)
{
///To get letters/alphabets
var letters = new String(item.Where(Char.IsLetter).ToArray());
///to get special characters
var letters = new String(item.Where(Char.IsSymbol).ToArray())
}
Now you can easily combine the codes :)
My front-end application sends strings that look like this:
"12-15"
to a back-end C# application.
Can someone give me some pointers as to how I could extract the two numbers into two variables. Note the format is always the same with two numbers and a hyphen between them.
string stringToSplit = "12-15";
string[] splitStringArray;
splitStringArray = stringToSplit.Split('-');
splitStringArray[0] will be 12
splitStringArray[1] will be 15
Split the string into parts:
string s = "12-15";
string[] num = s.Split('-');
int part1 = Convert.ToInt32(num[0]);
int part2 = Convert.ToInt32(num[1]);
int[] numbers = "12-15".Split('-')
.Select(x => {
int n;
int.TryParse(x, out n);
return n;
})
.ToArray();
We call Split on a string instance. This program splits on a single character
string s ="12-15";
string[] words = s.Split('-');
foreach (string word in words)
{
int convertedvalue = Convert.ToInt32(word );
Console.WriteLine(word);
}
string[] ss= s.Split('-');
int x = Convert.ToInt32(ss[0]);
int y = Convert.ToInt32(ss[1]);
more info
You can use the below code to split and it will return string for each value, then you can typecast it to any type you wish to ...
string myString = "12-15-18-20-25-60";
string[] splittedStrings = myString.Split('-');
foreach (var splittedString in splittedStrings)
{
Console.WriteLine(splittedString + "\n");
}
Console.ReadLine();
Here is the correct version without the wrong code
string textReceived = "12-15";
string[] numbers = textReceived.Split('-');
List<int> numberCollection = new List<int>();
foreach (var item in numbers)
{
numberCollection.Add(Convert.ToInt32(item));
}
String numberString = "12-15" ;
string[] arr = numberString.Split("-");
Now you will get a string array , you can use parsing to get the numbers alone
int firstNumber = Convert.ToInt32(arr[0]);
Helpful answer related to parsing :
https://stackoverflow.com/a/199484/5395773
You could convert that string explicitly to an integer array using Array.ConvertAll method and access the numbers using their index, you can run the below example here.
using System;
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
var number = "12-15";
var numbers = Array.ConvertAll(number.Split('-'), int.Parse);
Console.WriteLine(numbers[0]);
Console.WriteLine(numbers[1]);
}
}
}
Or you can explicitly convert the numeric string using int.Parse method, the int keyword is an alias name for System.Int32 and it is preffered over the complete system type name System.Int32, you can run the below example here.
using System;
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
var number = "12-15";
var numbers = number.Split('-');
var one = int.Parse(numbers[0]);
var two = int.Parse(numbers[1]);
Console.WriteLine(one);
Console.WriteLine(two);
}
}
}
Additional read: Please check int.Parse vs. Convert.Int32 vs. int.TryParse for more insight on parsing the input to integer
string str = null;
string[] strArr = null;
int count = 0;
str = "12-15";
char[] splitchar = { '-' };
strArr = str.Split(splitchar);
for (count = 0; count <= strArr.Length - 1; count++)
{
MessageBox.Show(strArr[count]);
}
I have a text file with lines of text laid out like so
12345MLOL68
12345MLOL68
12345MLOL68
I want to read the file and add commas to the 5th point, 6th point and 9th point and write it to a different text file so the result would be.
12345,M,LOL,68
12345,M,LOL,68
12345,M,LOL,68
This is what I have so far
public static void ToCSV(string fileWRITE, string fileREAD)
{
int count = 0;
string x = "";
StreamWriter commas = new StreamWriter(fileWRITE);
string FileText = new System.IO.StreamReader(fileREAD).ReadToEnd();
var dataList = new List<string>();
IEnumerable<string> splitString = Regex.Split(FileText, "(.{1}.{5})").Where(s => s != String.Empty);
foreach (string y in splitString)
{
dataList.Add(y);
}
foreach (string y in dataList)
{
x = (x + y + ",");
count++;
if (count == 3)
{
x = (x + "NULL,NULL,NULL,NULL");
commas.WriteLine(x);
x = "";
count = 0;
)
}
commas.Close();
}
The problem I'm having is trying to figure out how to split the original string lines I read in at several points. The line
IEnumerable<string> splitString = Regex.Split(FileText, "(.{1}.{5})").Where(s => s != String.Empty);
Is not working in the way I want to. It's just adding up the 1 and 5 and splitting all strings at the 6th char.
Can anyone help me split each string at specific points?
Simpler code:
public static void ToCSV(string fileWRITE, string fileREAD)
{
string[] lines = File.ReadAllLines(fileREAD);
string[] splitLines = lines.Select(s => Regex.Replace(s, "(.{5})(.)(.{3})(.*)", "$1,$2,$3,$4")).ToArray();
File.WriteAllLines(fileWRITE, splitLines);
}
Just insert at the right place in descending order like this.
string str = "12345MLOL68";
int[] indices = {5, 6, 9};
indices = indices.OrderByDescending(x => x).ToArray();
foreach (var index in indices)
{
str = str.Insert(index, ",");
}
We're doing this in descending order because if we do other way indices will change, it will be hard to track it.
Here is the Demo
Why don't you use substring , example
editedstring=input.substring(0,5)+","+input.substring(5,1)+","+input.substring(6,3)+","+input.substring(9);
This should suits your need.
My ultimate goal here is to turn the following string into JSON, but I would settle for something that gets me one step closer by combining the fieldname with each of the values.
Sample Data:
Field1:abc;def;Field2:asd;fgh;
Using Regex.Replace(), I need it to at least look like this:
Field1:abc,Field1:def,Field2:asd,Field2:fgh
Ultimately, this result would be awesome if it can be done via Regex in a single call.
{"Field1":"abc","Field2":"asd"},{"Field1":"def","Field2":"fgh"}
I've tried many different variations of this pattern, but can't seem to get it right:
(?:(\w+):)*?(?:([^:;]+);)
Only one other example I could find that is doing something similar, but just enough differences that I can't quite put my finger on it.
Regex to repeat a capture across a CDL?
EDIT:
Here's my solution. I'm not going to post it as a "Solution" because I want to give credit to one that was posted by others. In the end, I took a piece from each of the posted solutions and came up with this one. Thanks to everyone who posted. I gave credit to the solution that compiled, executed fastest and had the most accurate results.
string hbi = "Field1:aaa;bbb;ccc;ddd;Field2:111;222;333;444;";
Regex re = new Regex(#"(\w+):(?:([^:;]+);)+");
MatchCollection matches = re.Matches(hbi);
SortedDictionary<string, string> dict = new SortedDictionary<string, string>();
for (int x = 0; x < matches.Count; x++)
{
Match match = matches[x];
string property = match.Groups[1].Value;
for (int i = 0; i < match.Groups[2].Captures.Count; i++)
{
string key = i.ToString() + x.ToString();
dict.Add(key, string.Format("\"{0}\":\"{1}\"", property, match.Groups[2].Captures[i].Value));
}
}
Console.WriteLine(string.Join(",", dict.Values));
Now you have two problems
I don't think regular expressions will be the best way to handle this. You should probably start by splitting on semicolons, then loop through the results looking for a value that starts with "Field1:" or "Field2:" and collect the results into a Dictionary.
Treat this as pseudo code because I have not compiled or tested it:
string[] data = input.Split(';');
dictionary<string, string> map = new dictionary<string, string>();
string currentKey = null;
foreach (string value in data)
{
// This part should change depending on how the fields are defined.
// If it's a fixed set you could have an array of fields to search,
// or you might need to use a regular expression.
if (value.IndexOf("Field1:") == 0 || value.IndexOf("Field2:"))
{
string currentKey = value.Substring(0, value.IndexOf(":"));
value = value.Substring(currentKey.Length+1);
}
map[currentKey] = value;
}
// convert map to json
I had an idea that it should be possible to do this in a shorter and more clear way. It ended up not being all that much shorter and you can question if it's more clear. At least it's another way to solve the problem.
var str = "Field1:abc;def;Field2:asd;fgh";
var rows = new List<Dictionary<string, string>>();
int index = 0;
string value;
string fieldname = "";
foreach (var s in str.Split(';'))
{
if (s.Contains(":"))
{
index = 0;
var tmp = s.Split(':');
fieldname = tmp[0];
value = tmp[1];
}
else
{
value = s;
index++;
}
if (rows.Count < (index + 1))
rows.Insert(index, new Dictionary<string, string>());
rows[index][fieldname] = value;
}
var arr = rows.Select(dict =>
String.Join("," , dict.Select(kv =>
String.Format("\"{0}\":\"{1}\"", kv.Key, kv.Value))))
.Select(r => "{" + r + "}");
var json = String.Join(",", arr );
Debug.WriteLine(json);
Outputs:
{"Field1":"abc","Field2":"asd"},{"Field1":"def","Field2":"fgh"}
I would go with RegEx as the simplest and most straightforward way to parse the strings, but I'm sorry, pal, I couldn't come up with a clever-enough replacement string to do this in one shot.
I hacked it out for fun through, and the monstrosity below accomplishes what you need, albeit hideously. :-/
Regex r = new Regex(#"(?<FieldName>\w+:)*(?:(?<Value>(?:[^:;]+);)+)");
var matches = r.Matches("Field1:abc;def;Field2:asd;fgh;moo;"); // Modified to test "uneven" data as well.
var tuples = new[] { new { FieldName = "", Value = "", Index = 0 } }.ToList(); tuples.Clear();
foreach (Match match in matches)
{
var matchGroups = match.Groups;
var fieldName = matchGroups[1].Captures[0].Value;
int index = 0;
foreach (Capture cap in matchGroups[2].Captures)
{
var tuple = new { FieldName = fieldName, Value = cap.Value, Index = index };
tuples.Add(tuple);
index++;
}
}
var maxIndex = tuples.Max(tup => tup.Index);
var jsonItemList = new List<string>();
for (int a = 0; a < maxIndex+1; a++)
{
var jsonBuilder = new StringBuilder();
jsonBuilder.Append("{");
foreach (var tuple in tuples.Where(tup => tup.Index == a))
{
jsonBuilder.Append(string.Format("\"{0}\":\"{1}\",", tuple.FieldName, tuple.Value));
}
jsonBuilder.Remove(jsonBuilder.Length - 1, 1); // trim last comma.
jsonBuilder.Append("}");
jsonItemList.Add(jsonBuilder.ToString());
}
foreach (var item in jsonItemList)
{
// Write your items to your document stream.
}
I'm trying to implement a simple search function. I have a string array which contains all words which was typed in from the user to search. And I have another string which contains data like User Name, content... So what I want to do is to check is Name contains any of the elements in the search or String array. Right now I have a loop which checks one word at a time and concatenates the result in an IEnumerable.
Does anyone know a faster way of doing this search? Like String.ContainsAny(Search[])
Try this:
Search.Any(p => name.Contains(p))
using System.Linq;
string[] searchItems = ...
string input = "This is the input text";
// Check whether at least one match found
bool matchFound = input.Any(w => input.Contains(w));
// Count all matches
int matchesCount = input.Where(w => input.Contains(w))
.Count();
string[] searchItems = ...;
string[] userNames = ...;
var matches = userNames.Intersect(searchItems);
You can find more about the intersect method here
you can do like this...
return array.Any(s => s.Equals(myString))
or try like this....
string stringToCheck = "text1";
string[] stringArray = { "text1", "testtest", "test1test2", "test2text1" };
foreach (string x in stringArray)
{
if (x.Contains(stringToCheck))
{
// Process...
}
}
or Something like this
string stringToCheck = "text1text2text3";
string[] stringArray = new string[] { "text1" };
if (Array.Exists<string>(stringArray, (Predicate<string>)delegate(string s) {
return stringToCheck.IndexOf(s, StringComparison.OrdinalIgnoreCase) > -1; })) {
Console.WriteLine("Found!");
}
Two solutions to this problem for example:
Solution 1
private void findDateColumn() {
string stringToCheck = "date";
int stringToCheckIndex = -1;
string elementInArray = "Not Defined or Not Found";
if (Array.Exists<string> (headers, (Predicate<string>) delegate (string s)
{
stringToCheckIndex = s.IndexOf (stringToCheck,StringComparison.OrdinalIgnoreCase);
elementInArray = s;
return stringToCheckIndex > -1;
}))
{
dateColTitle.Text = elementInArray; //a textbox to show the output
}
}
Solution 2
I'm using #Lev answer, which seems simpler and shorter plus giving the same result:
private void setDateColumnTitle ()
{
dateColTitle.Text = "Not Defined or Not Found";
var match = headers.FirstOrDefault(c => c.IndexOf("date", StringComparison.OrdinalIgnoreCase) > -1);
if (match!=null)
dateColTitle.Text = match;
}