I wonder if there is a better way to parse signed integer using Sprache parser framework.
There is well known parser definition for integers without sign
Parse.Number.Select(int.Parse)
But I want to parse integers with - prefix as well.
What I have got right now is Parse.Regex(#"\-?\d+").Select(int.Parse).
Is there a better way to do that without using regular expressions?
For example use Parse.Char('-').Optional() and then parse following number.
Thanks
The way I do this is similar to the following:
from op in Parse.Optional(Parse.Char('-').Token())
from num in Parse.Decimal
from trailingSpaces in Parse.Char(' ').Many()
select decimal.Parse(num) * (op.IsDefined ? -1 : 1);
Of course, leave out the trailingSpaces portion depending on the context of what you're parsing.
Related
I have following code:
Decimal.TryParse("1.0e-50", NumberStyles.Float,CultureInfo.CurrentCulture.NumberFormat, out val)
I want to restrict it to e-45. Is there a way to do this without using regular expressions? I googled it but only best way i got was regex.
You should really just parse it as a decimal without bounds checking it, and then check the min/max values after you've parsed it into a numeric value. Trying to do the bounds checking on the string, before parsing it, is just asking for trouble; it'll be way more work, and more error prone.
Parse the value first and just compare it with a min/max value afterwards because there is no better way than regex to check how big the decimal value contained by the string is. All in all, parsing is much cleaner, efficient and I also would guess that it is faster.
ok so I am building a program in WPF format.
as you know wpf's inputs are usually string, to turn those into double first I need to validate if those string fit and then to proceed and convert them.
the problem is in the validation, I have done the part in the validation that is checking if the string.IsNullOrEmpty but the thing I could not do is validate if the answer is completely not convertable... let me show an example because some strings that are not completely numeric are still should be accepted for example:
"sadasdaasd" - not accepted (obviously)
"8945a4554" - not accepted (there is an 'a' in the middle)
"3519" - accepted
"12.55" - accepted
"-3/4" - accepted and the value should be converted to double as (-3) divided by (4). so '/' is accepted and it splits the string by 2 and then converts it to double as first part/ second part.
I have been trying to do this validation all day and still have not succeeded, I have tried searching the web for some input validation, some said that I need to use double.TryParse(string, out double) but this function does not work with the '/' split that i wanted. so please help me!!!
I would start by parsing your string via regex (q: is "-3*4" acceptable as -3 times 4?). Basically you're looking for a match on a regex which is kind of like this (this works on -3/4, you'd want to test it further and modify if multiplication is allowed): -?\d+[/]\d+
If you find that match, parse out your string with string.Split('/') which will give you an array of strings. TryParse each of those and do the math.
If there is not a match, use TryParse (as recommended previously). That will either succeed (3519, 12.55 in your examples) or fail (sadasdaasd, 8945a4554 in your examples).
Note: you could also use string.Contains('/'), but then you have to check to see if it holds more than one slash (unless such a thing is allowed- in which case you'll need to revisit that regex).
Ok, I need a general regular expression that will give me the x characters from a string starting at position y like the string's substring function:
input_str.Substring(y,x)
But as a C# regular expression.
Example:
1234567890 Substring(5,3) 678
I know you are thinking why not just use the Substring function? The short answer is because this goes as a data for an existing function and in this context it would be inelegant to create a whole separate data parsing mechanism. We'd like to get this working without changing the code.
I feel like this is really obvious--but I'm pretty inexperienced with regular expressions. Thanks in advance for any help.
.{y}(.{x}).* should do it, I think, then just pull out the capture group.
Is it possible somehow to do a RegEx-replace with a calculation in the result? (in VS2010)
Such as:
Grid\.Row\=\"{[0-9]+}\"
to
Grid.Row="eval(int(\1) + 1)"
You can use a MatchEvaluator do achieve this, like
String s = Regex.Replace("1239", #"\d", m => (Int32.Parse(m.ToString()) + 1).ToString());
Output: 23410
Edit:
I just noticed... if you mean "using the VS2010 find-replace feature" and not "using C#", then the answer is "no", i am afraid.
You could always use capturing to retrieve any values you need for your calculation and then perform a RegEx Replace with a new RegEx that's constructed from you're equation and any values you captured.
If the equation doesn't use anything from the input text, one RegEx would be sufficient. You'd simply construct it by concatenating the static portions together with the computed value(s).
Unfortunately, C# and .NET do not provide an eval method or equivalent. However, it is possible to either use a library for expression parsing (a quick google gave me this .NET Math Expression Parser) or write your own (which is actually pretty easy, check out the Shunting-yard Algorithm and Postfix Notation). Simply capture the group then output the group value to the library/method you have written.
Edit: I see now you want this for the VS2010 program. This is unachievable unless you write your own VS extension. You could always write a program to search and replace your code and feed the code into it, then replace it the original code with its output.
I am wondering if it is possible to extract the index position in a given string where a Regex failed when trying to match it?
For example, if my regex was "abc" and I tried to match that with "abd" the match would fail at index 2.
Edit for clarification. The reason I need this is to allow me to simplify the parsing component of my application. The application is an Assmebly language teaching tool which allows students to write, compile, and execute assembly like programs.
Currently I have a tokenizer class which converts input strings into Tokens using regex's. This works very well. For example:
The tokenizer would produce the following tokens given the following input = "INP :x:":
Token.OPCODE, Token.WHITESPACE, Token.LABEL, Token.EOL
These tokens are then analysed to ensure they conform to a syntax for a given statement. Currently this is done using IF statements and is proving cumbersome. The upside of this approach is that I can provide detailed error messages. I.E
if(token[2] != Token.LABEL) { throw new SyntaxError("Expected label");}
I want to use a regular expression to define a syntax instead of the annoying IF statements. But in doing so I lose the ability to return detailed error reports. I therefore would at least like to inform the user of WHERE the error occurred.
I agree with Colin Younger, I don't think it is possible with the existing Regex class. However, I think it is doable if you are willing to sweat a little:
Get the Regex class source code
(e.g.
http://www.codeplex.com/NetMassDownloader
to download the .Net source).
Change the code to have a readonly
property with the failure index.
Make sure your code uses that Regex
rather than Microsoft's.
I guess such an index would only have meaning in some simple case, like in your example.
If you'll take a regex like "ab*c*z" (where by * I mean any character) and a string "abbbcbbcdd", what should be the index, you are talking about?
It will depend on the algorithm used for mathcing...
Could fail on "abbbc..." or on "abbbcbbc..."
I don't believe it's possible, but I am intrigued why you would want it.
In order to do that you would need either callbacks embedded in the regex (which AFAIK C# doesn't support) or preferably hooks into the regex engine. Even then, it's not clear what result you would want if backtracking was involved.
It is not possible to be able to tell where a regex fails. as a result you need to take a different approach. You need to compare strings. Use a regex to remove all the things that could vary and compare it with the string that you know it does not change.
I run into the same problem came up to your answer and had to work out my own solution. Here it is:
https://stackoverflow.com/a/11730035/637142
hope it helps