i have a string that looks like this:
"/dir/location/test-load-ABCD.p"
and i need to parse out "ABCD" (where ABCD will be a different value every day)
The only things that i know that will always be consistent (to use for the logic for parsing) are:
There will always be be a ".p" after the value
There will always be a "test-load-" before the value.
The things i thought of was somehow grab everything past the last "/" and then remove the last 2 characters (to take case of the ".p" and then to do a
.Replace("test-load-", "")
but it felt kind of hacky so i wanted to see if people had any suggestions on a more elegant solution.
You can use a regex:
static readonly Regex parser = new Regex(#"/test-load-(.+)\.p");
string part = parser.Match(str).Groups[1].Value;
For added resilience, replace .+ with a character class containing only the characters that can appear in that part.
Bonus:
You probably next want
DateTime date = DateTime.ParseExact(part, "yyyy-MM-dd", CultureInfo.InvariantCulture);
Since this is a file name, use the file name parsing facility offered by the framework:
var fileName = System.IO.Path.GetFileNameWithoutExtension("/dir/location/test-load-ABCD.p");
string result = fileName.Replace("test-load-", "");
A “less hacky” solution than using Replace would be the use of regular expressions to capture the solution but I think this would be overkill in this case.
string input = "/dir/location/test-load-ABCD.p";
Regex.Match(input, #"test-load-([a-zA-Z]+)\.p$").Groups[1].Value
Related
I have a line of code, something like:
mbar.HealthLabel.text = String.Format("{0:0.0}", _hp);
Output is: 2.25 for example. Is it possible to escape a dot from the output string view with String.Format function ?
For. ex. 225,
To make my question more clear, I need the same effect like:
Math.Floor(_hp * 100).ToString();
But need to do it by String.Format template.. Thanks.
Simply you can do it this way
double value = 1.25;
var stringValue = string.Format("{0:0}", value * 100, CultureInfo.InvariantCulture); //125
EDIT:
More general solution would be to Replace the dot with empty string as stated in the comments.
double value = 1.25;
var stringValue = value.ToString(CultureInfo.InvariantCulture).Replace(".",string.Empty);
EDIT2: Also there is another general idea that do not use Replace function (but also it does not use the String.Format)
var stringValue = string.Join("", value.ToString().Where(char.IsDigit));
Also another similar idea:
var stringValue = new string(value.ToString().Where(char.IsDigit).ToArray());
First of all, please read my comment to the question. As i mentioned there, string format for numeric values depends on regional settings. So, below line
mbar.HealthLabel.text = String.Format("{0:0.0}", _hp);
will return: 2,25 (as to the polish numeric standard)
In my opinion you need something like this:
mbar.HealthLabel.text = String.Format("{0:D}", Math.Floor(_hp*100));
For furhter details, please see:
Standard Numeric Format Strings
Custom Numeric Format Strings
Up to Microsoft.NET Framework 4.7 there is no way to solve this when we are only allowed to modify the format string ("template"). All solutions require to either:
Post-process the resulting string. Here, the closest for the special case with two decimals may be the % format
Compute the numeric argument first to make it integer
Write and apply a custom IFormatProvider implementation
If you want to eliminate the decimal separtor ("escape the dot", as you've put it), try replacing the decimal separator with empty string:
string result = String
.Format("{0:0.0}", _hp)
.Replace(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, "");
I will have always an string like this:
"/FirstWord/ImportantWord/ThirdWord"
How can I extract the ImportantWord? Words can contain at most one space and they are separated by forward slashlike I put above, for example:
"/Folder/Second Folder/Content"
"/Main folder/Important/Other Content"
I always want to get the second word(Second Folder and Important considering above examples)
how about this:
string ImportantWord = path.Split('/')[2]; // Index 2 will give the required word
I hope you need not to use the String.Split option either with specific characters or with some regular expressions. Since the inputs are well qualified paths to a directory you can use Directory.GetParent method of the System.IO.Directory class, which will give you the parent Directory as DirectoryInfo. From that you can take the Name of Directory which will be the required text.
You can use like this :
string pathFirst = "/Folder/Second Folder/Content";
string pathSecond = "/Main folder/Important/Other Content";
string reqWord1 = Directory.GetParent(pathFirst ).Name; // will give you Second Folder
string reqWord2 = Directory.GetParent(pathSecond).Name; // will give you Important
Additional note: The method Directory.GetParent can be nested if you need to get a name in another level.
Also you may try this:
var stringValue = "/FirstWord/ImportantWord/ThirdWord";
var item = stringValue.Split('/').Skip(2).First(); //item: ImportantWord
There are several ways to solve this. The simplest one is using String.split
Char delimiter = '/';
String[] substrings = value.Split(delimiter);
String secondWord = substrings[1];
(you may want to do some input check to make sure the input is in the right format or else you will get some exception)
Other way is using regex when the pattern is simple /
If you are sure this is a path you can use other answer mention here
I am trying to parse through some log files and put them into a database for analysis. A single line looks something like this:
2012-09-30 17:16:27,213 [39] (boxes) ERROR Assembly.Places [(null)] - Error while displaying a thing
I have made a regular expression that works well for pulling out the date in front and breaking up the lines that way, but I lose the date itself. This is a pretty important bit of data, and I don't want to lose it!
I cannot just do this by \r\n, because some logs are fatal errors that include stack traces for the developers. Those, obviously, use \r\n to make them readable.
My current code looks like this for reference:
var logpath = Directory.GetFiles(#"C:\a\directory", "*.log");
foreach (var log in logpath)
{
var fileStream = new StreamReader(log);
var fileString = fileStream.ReadToEnd();
var records = Regex.Split(fileString, "[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3}");
...
}
Split() will always remove the matched delimiter. The trick is not to match any actual text, but rather a position in the string.
This is done through zero-width look-ahead:
var datePattern = "^(?=[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3})";
var datePositions = new Regex(datePattern, RegexOptions.Multiline);
// ...
Regex.Split(fileString, datePositions);
You should match instead of splitting
This is the regex.Use singleLine Mode
([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3})(.*?)((?=[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3}|$))
Group 1 contains date
Group 2 contains the required date
NOTE
The regex is conceptually like this.
(yourDate)(.*?yourdata)(?=till the other date|$)
Dont forget to use singlelineMode
Well, I'm not an expert on the subject but I did found this: Regex.Match.
From what I see you can receive the first match of the date format with a Match object
which has all kind of nice properties that put together you can probably cut the parts you want.
p.s. also exists a Regex.Matches which will return all matches in the file, might be easier for use.
Sorry I don't have time for to find a complete code example.
good day
I have the following string:
http://www.powerwXXe.com/text1 123-456 text2 text3/
Can someone give me advice on how to get the value of text1, text2 and text3 and put them into a string. I have heard of regular expressions but have no idea how to use them.
Instead of going the RegEx route, if you know that the string will always be of a similar format, you can using string.Split, first on /, then on space and retrieve the results from the resulting string arrays.
string[] slashes = myString.Split('/');
string[] textVals = slashes[3].Split(' ');
// at this point:
// textVals[0] = "text1"
// textVals[1] = "123-456"
// textVals[2] = "text2"
// textVals[3] = "text3"
Here is a link on getting started with regular expressions in C#:Regular Expression Tutorial
I don't think it is appropriate to write out a tutorial here since the information is online, so please check out the link and let me know if you have a specific question.
Instead of using regex, you can use string.Fromat("http://myurl.com/{0}{1}{2}", value1, textbox2.Text, textbox3.Text) and format the url in whatever fashion. If you are looking to go the regex route, you can always check regexlib.
The use of regular expressions relies on patterns you see in your strings - you need to be able to generalize the pattern of strings you're looking for before you can use a regular expression.
For a problem of this scope, if you can pin down the pattern, you're probably better off using other string parsing methods, such as String.IndexOf and String.Split.
Regular expressions is a powerful tool, and certainly worth learning, but it might not be necessary here.
Based on the example you gave, it looks as though text1, text2 and text3 are separated by spaces? If so, and if you always know the positions they'll be in, you may want to skip regular expressions and just use .Split(' ') to split the string into an array of strings and then grab the pertinent items from there. Something like this:
string foo = "http://www.powerwXXe.com/text1 123-456 text2 text3/"
string[] fooParts = foo.Split(' ');
string text1 = fooParts[0].Replace("http://www.powerwXXe.com/", "");
string text2 = fooParts[2];
string text3 = fooParts[3].Replace("/", "");
You'd want to perform bounds checking on the string[] before trying to grab anything from it, but this would work. Regex is awesome for string parsing, but when it's simple stuff you need to do, sometimes it's overkill when simple methods from the string class will do.
It all depends on how much you know about about the string you are parsing. Where does the string come from and how much do you know about it's formating?
Based on your example string you could get away with something as simple as
string pattern = #"http://www.powerwXXe.com/(?<myGroup1>\S+)\s\S+\s(?<myGroup2>\S+)\s(?<myGroup3>\S+)/";
var reg = new System.Text.RegularExpressions.Regex(pattern);
string input = "http://www.powerwXXe.com/text1 123-456 text2 text3/";
System.Text.RegularExpressions.Match myMatch = reg.Match(input);
The caputerd strings would then be contained in myMatch.Groups["myGroup1"], ["myGroup2"], ["myGroup3"] respectivly.
This however assumes that your string always begins with http://www.powerwXXe.com/, that there will always be three groups to capture and that the groups are separated by a space (which is an illegal character in url's and would in almost all cases be converted to %20, which would have to be accounted for in the pattern).
So, how much do you know about your string? And, as some has already stated, do you really need regular expressions?
How can I change values in string from 0,00 to 0.00? - only numeric values, not all chars "," to "."
FROM
string myInputString = "<?xml version=\"1.0\"?>\n<List xmlns:Table=\"urn:www.navision.com/Formats/Table\"><Row><HostelMST>12,0000</HostelMST><PublicMST>0,0000</PublicMST><TaxiMST>0,0000</TaxiMST><ParkMST>0,0000</ParkMST><RoadMST>0,0000</RoadMST><FoodMST>0,0000</FoodMST><ErrorCode>0</ErrorCode><ErrorDescription></ErrorDescription></Row></List>\n";
TO
string myInputString = "<?xml version=\"1.0\"?>\n<List xmlns:Table=\"urn:www.navision.com/Formats/Table\"><Row><HostelMST>12.0000</HostelMST><PublicMST>0.0000</PublicMST><TaxiMST>0.0000</TaxiMST><ParkMST>0.0000</ParkMST><RoadMST>0.0000</RoadMST><FoodMST>0.0000</FoodMST><ErrorCode>0</ErrorCode><ErrorDescription></ErrorDescription></Row></List>\n";
Thanks for answers, but I mean to change only numeric values, not all chars "," to "."
I don't want change string from
string = "<Attrib>txt txt, txt</Attrib><Attrib1>12,1223</Attrib1>";
to
string = "<Attrib>txt txt. txt</Attrib><Attrib1>12.1223</Attrib1>";
but this one is ok
string = "<Attrib>txt txt, txt</Attrib><Attrib1>12.1223</Attrib1>";
Try this :
Regex.Replace("attrib1='12,34' attrib2='43,22'", "(\\d),(\\d)", "$1.$2")
output : attrib1='12.34' attrib2='43.22'
The best method depends on the context. Are you parsing the XML? Are you writing the XML. Either way it's all to do with culture.
If you are writing it then I am assuming your culture is set to something which uses commas as decimal seperators and you're not aware of that fact. Firstly go change your culture in Windows settings to something which better fits your culture and the way you do things. Secondly, if you were writing the numbers out for human display then I would leave it as culturally sensative so it will fit whoever is reading it. If it is to be parsed by another machine then you can use the Invariant Culture like so:
12.1223.ToString(CultureInfo.InvariantCulture);
If you are reading (which I assume is what you are doing) then you can use the culture info again. If it was from a human source (e.g. they typed it in a box) then again use their default culture info (default in float.Parse). If it is from a computer then use InvariantCulture again:
float f = float.Parse("12.1223", CultureInfo.InvariantCulture);
Of course, this assumes that the text was written with an invariant culutre. But as you're asking the question it's not (unless you have control over it being written, in which case use InvariantCulture to write it was suggested above). You can then use a specific culture which does understand commas to parse it:
NumberFormatInfo commaNumberFormatInfo = new NumberFormatInfo();
commaNumberFormatInfo.NumberDecimalSeperator = ",";
float f = float.Parse("12,1223", commaNumberFormatInfo);
I strongly recommend joel.neely's regex approach or the one below:
Use XmlReader to read all nodes
Use double.TryParse with the formatter = a NumberFormatInfo that uses a comma as decimal separator, to identify numbers
Use XmlWriter to write a new XML
Use CultureInfo.InvariantCulture to write the numbers on that XML
The answer from ScarletGarden is a start, but you'll need to know the complete context and grammar of "numeric values" in your data.
The problem with the short answer is that cases such as this get modified:
<elem1>quantity<elem2>12,6 of which were broken</elem2></elem1>
Yes, there's probably a typo (missing space after the comma) but human-entered data often has such errors.
If you include more context, you're likely to reduce the false positives. A pattern like
([\s>]-?$?\d+),(\d+[\s<])
(which you can escape to taste for your programming language of choice) would only match when the "digits-comma-digits" portion (with optional sign and currency symbol) was bounded by space or an end of an element. If all of your numeric values are isolated within XML elements, then you'll have an easier time.
string newStr = myInputString.Replace("0,00", "0.00");
While you could theoretically do this using a Regex, the pattern would be complex and hard to to test. ICR is on the right track, you need to do this based on culture.
Do you know that your numbers are always going to be using a comma as a decimal separator instead of a period? It looks like you can, given that Navision is a Danish company.
If so, you'll need to traverse the XML document in the string, and rewrite the numeric values. It appears you can determine this on node name, so this won't be an issue.
When you convert the number, use something similar to this:
here's what you want to do:
internal double ConvertNavisionNumber(string rawValue)
{
double result = 0;
if (double.TryParse(rawValue, NumberStyles.Number, new CultureInfo("da-DK").NumberFormat, out result))
return result;
else
return 0;
}
This tells the TryParse() method that you're converting a number from Danish (da-DK). Once you call the function, you can use ToString() to write the number out in your local format (which I'm assuming is US or Canadian) to get a period for your decimal separator. This will also take into account numbers with different thousands digit separator (1,234.56 in Canada is written as 1 234,56 in Denmark).
ConvertNavisionNumber("4,43").ToString()
will result in "4.43".
ConvertNavisionNumber("1 234").ToString()
will result in "1,234".
if the , is not used anywhere else but number with in the string you can use the following:
string newStr = myInputString.Replace(",", ".");