I'm developing Windows Phone app which consuming web API calls. Most of call are returning JSON strings, but one of them return the following line of code:
var buyPrice=[[Date.UTC(2012,0,9),385.250000], [Date.UTC(2012,0,10),386.250000], [Date.UTC(2012,0,11),387.000000]];
It seems that above mentioned line of code is a regular declaration of JavaScript collection. It does mean I can't parse it as JSON, moreover it contains a word
"var buyPrice="
which can't be parsed as well.
So I need to convert above mentioned collection to the corresponding C# array/collection, but not sure I'm able to do that.
Is it possible to do this by using C# abilities or I need some third party library?
Without external librairies (and I don't know any for this kind of tasks), you can use Regex:
var input = "var buyPrice=[[Date.UTC(2012,0,9),385.250000], [Date.UTC(2012,0,10),386.250000], [Date.UTC(2012,0,11),387.000000]];"
var regex = #"\[Date.UTC\((?<year>\d{4}),(?<month>\d{1,2}),(?<day>\d{1,2})\),(?<price>\d+(\.\d+)?)]";
var matches = Regex.Matches(input, regex)
.OfType<Match>()
.Select(m => new
{
Date = new DateTime(
Int32.Parse(m.Groups["year"].Value),
Int32.Parse(m.Groups["month"].Value) + 1,
Int32.Parse(m.Groups["day"].Value)
),
Price = Decimal.Parse(m.Groups["price"].Value)
});
Because Date.UTC takes a month starting from 0, you have to add one. Based on your input, this will return three anonymous object with a Datetime Date and decimal Price properties.
Note that this Regex does not try to validate the input (the month and day 00-99 is valid), but it's a good starting point.
Related
So I fetch a string from a website via code from another question I posted here. This works really well when I put it into a rich textbox, but, now I need to split the string into seperate sentences in a list/array (suppose list will be easier, since you don't need to determine how long the input is going to be).
Yesterday I found the following code at another question (didn't note the question, sorry):
List<string> list = new List<string>(Regex.Split(lyrics, Environment.NewLine));
But the input is now spliting into two parts, the first three sentences and the rest.
I retrieve the text from musixmatch.com with the following code (added fixed url for simplicity):
var source = "https://www.musixmatch.com/lyrics/Krewella/Alive";
var htmlWeb = new HtmlWeb();
var documentNode = htmlWeb.Load(source).DocumentNode;
var findclasses = documentNode
.Descendants("p")
.Where(d => d.Attributes["class"]?.Value.Contains("mxm-lyrics__content") == true);
var text = string.Join(Environment.NewLine, findclasses.Select(x => x.InnerText));
More information about this code can be found here. What it does in a nutshell is it retrieves specific html that has the lyrics in it. I need to split the lyrics line by line for a synchronization process that I'm building (just like was built-in in Spotify a while ago). I need something (preferably an list/array) that I can index because that would make the database to store all this data a bit smaller. What am I supposed to use for this process?
Edit:
Answer to the mark of a possible duplicate:
C# Splitting retrieved string to list/array
You can split by both:
var lines = string.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
What I would do is to ensure that there is a common concept of "NewLine" in the code. It could be \r, \n or \r\n. Simply replace all '\n' with "". (Edited this one)
Now, all you have to do is
var lyricLines = lyricsWithCommonNewLine.Split('\r')
I have a string input in the format of "string#int" and I want to convert it to "string-int" for web friendliness reasons for an api i am using.
To do this I could obviously just replace the single character # with a - using string.replace, but ideally I'd like to do a check that the input (which is user provided by the way) is in the correct format (string#int) while or before converting to the web friendly version with a "-" instead. Essentially I'm wondering if there is a method in C# that I could use to check that this input is in the correct format and convert it to the required result format.
There is no built-in way obviously, since the format you request is quite specific. Also, a string can contain anything, also a hastag, #, so I guess you need to narrow that down.
You could use regular expressions to check if the string is in the correct format. This would be possible expression:
[A-Za-z ]+#[0-9]+
Which matches for:
this is a string#123
There's nothing built in, but you could do the following:
var parts = input.Split(new char[] { '#' });
if (parts.Length != 2) incorrect format
int result;
if (!int.TryParse(parts[1], out result) incorrect format
output = String.Join("-", parts);
This takes the input and splits it on the "#" character. If the result isn't two parts then the string is invalid. You then check that the second part is an integer - if the TryParse fails it's not valid. The last step is to rejoin the two parts, but this time with a - as the separator.
I am reading a couple of csv files into var's as follows:
var myFullCsv = ReadFile(myFullCsvFilePath);
var masterCsv = ReadFile(csvFilePath);
Some of the line entries in each csv appear in both files and I am able to create a new var containing lines that exists in myFullCsv but not in masterCsv as follows:
var extraFilesCsv = myFullCsv.Except(masterCsv);
This is great because its very simple. However, I now wish to identify lines in myFullCsv where a specific string appears in the line. The string will correspond to one column of the csv data. I know that I can do this by reading each line of the var and splitting it up, then comparing the field I'm interested in to the string that I am searching for. However, this seems like a very long and inefficient approach as compared to my code above using the 'Except' command.
Is there some way that I can get the lines from myFullCsv with a very simple command or will I have to do it the long way? Please don't ask me to show the long way as that's what I am trying to avoid having to code although I can do it.
Sample csv data:
07801.jpg,67466,9452d316,\Folder1\FolderA\,
07802.jpg,78115,e50492d8,\Folder1\FolderB\,
07803.jpg,41486,37b6a100,\Folder1\FolderC\,
07804.jpg,93500,acdffc2b,\Folder2\FolderA\,
07805.jpg,67466,9452d316,\Folder2\FolderB\,
Sample desired output (I'm always looking for the entry in the 3rd column to match a string, in this case 9452d316):
07801.jpg,67466,9452d316,\Folder1\FolderA\,
07805.jpg,67466,9452d316,\Folder2\FolderB\,
Well you could use:
var results = myFullCsv.Where(line => line.Split(',')[2] == targetValue)
.ToList();
That's just doing the "splitting and checking" you mention in the question but it's pretty simple code. It could be more efficient if you only consider as far as the third comma, but I wouldn't worry about that until it's proved to be a problem.
Personally I'd probably parse each line to an object with meaningful properties rather than treating is as a string, but that's probably what you mean by "the long way".
Note that this doesn't perform any validation, or try to handle escaped commas, or lines with fewer columns etc. Depending on your data source, you may need to make it a lot more robust.
You could use a regex. It doesn't require every line to have at least 3 elements. It doesn't allocate a string array for each line. Therefore it may be faster, but you'd have to test it to prove it.
var regex = new Regex("^.+?,.+?," + Regex.Escape(targetValue) + ",");
var results = myFullCsv.Where(l => regex.IsMatch(l)).ToList();
This question already has answers here:
Getting required information from Log file using Split
(4 answers)
Closed 9 years ago.
I am reading a text file to upload it into database. The text file contains like this with no headers...
[10-10-2013 11:20:33.444 CDF] 1000020 Incident T This is the error message
[10-10-2013 11:20:33.445 CDF] 1000020 Incident T This is the second error message
How can I store "10-10-2013 11:20:33" in Date Column and milliseconds 444 in integer column of database. Here if I try to use split with space first, it will split date into 3 parts. I want to get date between the brackets and then get the rest with split spaces.
Two points to mention here.
1. Here we have spaces in between date column.
2. Also I should be able to get other columns
The real simplest way to do this is to use regular expressions, not gobs of split and indexof operations.
Regular expressions allow you to specify a pattern out of which pieces of a string can be extracted in a straightforward fashion. If the format changes, or there is some subtlety not initially accounted for, you can fix the problem by adjusting the expression, rather than rewriting a bunch of code.
Here's some documentation for regular expressions in .NET: http://msdn.microsoft.com/en-us/library/az24scfc.aspx
This is some sample code that'll probably do what you want. You may need to tweak a little to get the desired results.
var m = Regex.Match(currentLine, #"^\[(?<date>[^\]]*)\]\s+(?<int>[0-9]+)\s+(?<message>.*)\s*$");
if(m.Success) {
// may need to do something fancier to parse the date, but that's an exercise for the reader
var myDate = DateTime.Parse(m.Groups["date"].Value);
var myInt = int.Parse(m.Groups["int"].Value);
var myMessage = m.Groups["message"].Value;
}
The simplest way to do this is to just use String.Split and String.Substring
Generically I would do this:
//find the indices of the []
var leftIndex = currentLine.IndexOf("[");
var rightIndex = currentLine.IndexOf("]");
//this get's the date portion of the string
var dateSubstring = currentLine.Substring(leftIndex, rightIndex - leftIndex);
var dateParts = dateSubstring.Split(new char[] {'.'});
// get the datetime portion
var dateTime = dateParts[0];
var milliseconds = Int16.Parse(dateParts[1]);
EDIT
Since the date portion is fixed width you could just use Substring for everything.
I want to search for all possible dates in a string using Regex.
In my code i have this:
String dateSearchPattern = #"(?<Day>\d{2}).(?<Month>\d{2}).(?<Year>\d{4})|(?<Day>\d{2}).(?<Month>\d{2}).(?<Year>\d{2})";
// date format: dd.mm.yyyy or d.m.yyyy or dd.mm.yy or d.m.yy
String searchText = "20.03.2010.25.03.10";
Regex.Matches(searchText, dateSearchPattern); // the matching SHOULD give a count of 2
The above code gives only 1 match where it should give 2. Also i need to have a patthern when the date format is like d.m.yyyy or d.m.yy.
The pattern seems perfectly ok. It is giving two match. By any chance have you used the following line to check the count?
var match = Regex.Matches(searchText, dateSearchPattern);
Console.WriteLine(match.Count);
I used SD 3 on .Net 3.5 (w/o sp1) and your code is giving your desired result.
You can change your pattern to this:
"(?<Day>\d{1,2}).(?<Month>\d{1,2}).(?:(?<Year>\d{4})|(?<Year>\d{2}))"