I know there are many questions about making regular expressions, but they all seem to be about a single problem than the general usage. I, too, have a problem like to solve. I have tried to learn by reading about regular expressions, but it gets tricky quick. Here's my question:
C#
I need to validate two textboxes that exist on the same form. The math operations I've coded can handle any floating point number. For this particular application I know of three formats the numbers will be in or there is a mistake on the users behalf. I'd like to prevent those mistakes in example if an extra number is accidentally typed or if enter is hit too early, etc.
Here are the formats: "#.####" "##.####" "###.##" where the "#" represents a mandatory digit. The formats starting with a one or two digit whole number must have 4 trailing digits or more. I've capped it at 8, or so I tried to lol.The format starting with a three digit whole number should never be allowed to have more than two digits trailing the decimal.
Here's what I have tried thus far.
Regex acceptedInputRegex = new Regex(#"^\b[0-9]{3}.[0-9]{2}|[0-9]{1,2}.[0-9]{4,8}$");
Regex acceptedInputRegex = new Regex(#"^\b\d{3}.\d{2} | \d{1,2}.\d{4,8}$");
I have tried it in thinking a match was what I wanted to achieve and as if a match to my negated expression means there is a problem. I was unsuccessful in both attempts. This is the code:
if (acceptedInputRegex.IsMatch(txtMyTextBox1.Text) || acceptedInputRegex.IsMatch(txtMyTextBox2.Text))
{
} else
{
MessageBox.Show("Numbers are not in the right format", "Invalid Input!");
return;
}
Are regular expressions what I should be using to solve this problem?
If not, please tell me what you recommend. If so, please help me correct my regex.
Thanks.
You are close, you need to escape the dots and group the alternatives so that the ^ and $ anchors could be applied to both of them:
#"^(?:\d{3}\.\d{2}|\d{1,2}\.\d{4,8})$"
See the regex demo.
Details:
^ - start of string
(?: - start of a non-capturing group matching either of the two alternatives:
\d{3}\.\d{2} - 3 digits, . and 2 digits
| - or
\d{1,2}\.\d{4,8} - 1 or 2 digits, ., 4 to 8 digits
) - end of the non-capturing group
$ - end of string.
To make \d match only ASCII digits, use RegexOptions.ECMAScript option:
var isValid = Regex.IsMatch(s, #"^(?:\d{3}\.\d{2}|\d{1,2}\.\d{4,8})$", RegexOptions.ECMAScript);
Related
I want to match strings that do not contain more than 3 of the same character repeated in a row. So:
abaaaa [no match]
abawdasd [match]
abbbbasda [no match]
bbabbabba [match]
Yes, it would be much easier and neater to do a regex match for containing the consecutive characters, and then negate that in the code afterwards. However, in this case that is not possible.
I would like to open out the question to x consecutive characters so that it can be extended to the general case to make the question and answer more useful.
Negative lookahead is supported in this case.
Use a negative lookahead with back references:
^(?:(.)(?!\1\1))*$
See live demo using your examples.
(.) captures each character in group 1 and the negative look ahead asserts that the next 2 chars are not repeats of the captured character.
To match strings not containing a character repeated more than 3 times consecutively:
^((.)\2?(?!\2\2))+$
How it works:
^ Start of string
(
(.) Match any character (not a new line) and store it for back reference.
\2? Optionally match one more exact copies of that character.
(?! Make sure the upcoming character(s) is/are not the same character.
\2\2 Repeat '\2' for as many times as you need
)
)+ Do ad nauseam
$ End of string
So, the number of /2 in your whole expression will be the number of times you allow a character to be repeated consecutively, any more and you won't get a match.
E.g.
^((.)\2?(?!\2\2\2))+$ will match all strings that don't repeat a character more than 4 times in a row.
^((.)\2?(?!\2\2\2\2))+$ will match all strings that don't repeat a character more than 5 times in a row.
Please be aware this solution uses negative lookahead, but not all not all regex flavors support it.
I'm answering this question :
Is there a regular expression for matching a string that has no more than 2 repeating characters?
which was marked as an exact duplicate of this question.
Its much quicker to negate the match instead
if (!Regex.Match("hello world", #"(.)\1{2}").Success) Console.WriteLine("No dups");
I'm trying to modify a fairly basic regex pattern in C# that tests for phone numbers.
The patterns is -
[0-9]+(\.[0-9][0-9]?)?
I have two questions -
1) The existing expression does work (although it is fairly restrictive) but I can't quite understand how it works. Regexps for similar issues seem to look more like this one -
/^[0-9()]+$/
2) How could I extend this pattern to allow brackets, periods and a single space to separate numbers. I tried a few variations to include -
[0-9().+\s?](\.[0-9][0-9]?)?
Although i can't seem to create a valid pattern.
Any help would be much appreciated.
Thanks,
[0-9]+(\.[0-9][0-9]?)?
First of all, I recommend checking out either regexr.com or regex101.com, so you yourself get an understanding of how regex works. Both websites will give you a step-by-step explanation of what each symbol in the regex does.
Now, one of the main things you have to understand is that regex has special characters. This includes, among others, the following: []().-+*?\^$. So, if you want your regex to match a literal ., for example, you would have to escape it, since it's a special character. To do so, either use \. or [.]. Backslashes serve to escape other characters, while [] means "match any one of the characters in this set". Some special characters don't have a special meaning inside these brackets and don't require escaping.
Therefore, the regex above will match any combination of digits of length 1 or more, followed by an optional suffix (foobar)?, which has to be a dot, followed by one or two digits. In fact, this regex seems more like it's supposed to match decimal numbers with up to two digits behind the dot - not phone numbers.
/^[0-9()]+$/
What this does is pretty simple - match any combination of digits or round brackets that has the length 1 or greater.
[0-9().+\s?](\.[0-9][0-9]?)?
What you're matching here is:
one of: a digit, round bracket, dot, plus sign, whitespace or question mark; but exactly once only!
optionally followed by a dot and one or two digits
A suitable regex for your purpose could be:
(\+\d{2})?((\(0\)\d{2,3})|\d{2,3})?\d+
Enter this in one of the websites mentioned above to understand how it works. I modified it a little to also allow, for example +49 123 4567890.
Also, for simplicity, I didn't include spaces - so when using this regex, you have to remove all the spaces in your input first. In C#, that should be possible with yourString.Replace(" ", ""); (simply replacing all spaces with nothing = deleting spaces)
The + after the character set is a quantifier (meaning the preceeding character, character set or group is repeated) at least one, and unlimited number of times and it's greedy (matched the most possible).
Then [0-9().+\s]+ will match any character in set one or more times.
First time posting, please forgive the formatting. Not really a programmer, I work in C# with the Revit and AutoCAD APi's. Important to note, as the Revit API is a bit of mess, so the same code may produce different results in a different API. So I have three basic string patterns where I want to return certain numbers depending on what their prefix & suffix. They could be surrounded by other text than what I show, and the actual numbers and positions within the string may vary.
String 1: (12) #4x2'-0 # 6 EF
String 2: (12) #4 # 6 EF
String 3: STAGGER 2'-0, SPCG AT 6 AT 12 SLAB
The code I'm using:
if (LengthAsString.IsMatch(remarkdata) == true)
{
Regex remarklength = new Regex(#"isnertRegexPatternhere");
if (remarklength.IsMatch(remarkdata))
{
remarkdata = remarklength.Replace(remarkdata, "${0}\u0022");
}
}
remarkdata is the strings from above, and im adding inch marks " after each number match.
The patterns ive tested and their returns:
String 1 String 2 String 3
\d+(?!['-]|([(\d+)])) 0,6 4,6 0,6,12
(?<![#])\d+ 12,2,0,6 12,6 2,9,6,12
\d+(?= #)|(?<=# )\d+ 0,6 6 no matches
expected results: 0,6 6 0,6,12
so im close, but no cigar. Thoughts?
Double Edit: looking for the numbers that aren't preceded by #, nor between (). Ignore # and x, they may or may not be there.
You seem to be looking for
(?<!#)\d+(?!.*(?:['-]|[#x]\d))
See the regex demo
Details
(?<!#) - a negative lookbehind that fails the match if there is a # immediately to the left of the current location
\d+ - 1 or more digits (or [0-9]+ to only match ASCII digits)
(?!.*(?:['-]|[#x]\d)) - a negative lookahead that fails the match once there are any 0+ chars other than newline (.*) followed with ', -, or #/x followed with a digit immediately to the right of the current location.
Note that in case your strings always have balanced non-nested parentheses, and you may have (123) substrings after # or x1, you may also want to add [^()]*\) into the lookahead
(?<!#)\d+(?!.*(?:['-]|[#x]\d)|[^()]*\))
to avoid matching digits inside the parentheses.
See another .NET demo.
I need a regular expression validation expression that will
ALLOW
positive number(0-9)
, and .
DISALLOW
letter(a-z)
any other letter or symbol except . and ,
for example, on my asp.net text box, if I type anything#!#--, the regular expression validation will disallow it, if I type 10.000,50 or 10,000.50 it should allowed.
I've been trying to use this regex:
^\d+(\.\d\d)?$
but my textbox also must allow , symbol and I tried using only integer regex validation, it did disallow if I type string, but it also disallow . and , symbol while it should allow number(0-9) and also . and , symbol
Don't Use \d to match [0-9] in .NET
First off, in .NET, \d will match any digits in any script, such as:
654۳۲١८৮੪૯୫୬१७੩௮௫౫೮൬൪๘໒໕២៧៦᠖
So you really want to be using [0-9]
Incomplete Spec
You say you want to only allow "digits, commas and periods", but I don't think that's the whole spec. That would be ^[0-9,.]+$, and that would match
...,,,
See demo.
Tweaking the Spec
It's hard to guess what you really want to allow: would 10,1,1,1 be acceptable?
We could start with something like this, to get some fairly well-formed strings:
^(?:[0-9]+(?:[.,][0-9]+)?|[1-9][0-9]{0,2}(?:(?:\.[0-9]{3})*|(?:,[0-9]{3})*)(?:\.[0-9]+)?)$
Play with the demo, see what should and shouldn't match... When you are sure about the final spec, we can tweak the regex.
Sample Matches:
0
12
12.123
12,12
12,123,123
12,123,123.12456
12.125.457.22
Sample Non-Matches:
12,
123.
1,1,1,1
Your regex would be,
(?:\d|[,\.])+
OR
^(?:\d|[,\.])+$
It matches one or more numbers or , or . one or more times.
DEMO
Maybe you can use this one (starts with digit, ends with digit):
(\d+[\,\.])*\d+
If you need more sophisticated price Regex you should use:
(?:(?:[1-9]\d?\d?([ \,\.]?\d{3})*)|0)(?:[\.\,]\d+)?
Edit: To make it more reliable (and dont get 00.50) you can add starting and ending symbol check:
(^|\s)(?:(?:[1-9]\d?\d?([ \,\.]?\d{3})*)|0)(?:[\.\,]\d+)($|\s)?
I think the best regex for your condition will be :
^[\d]+(?:,\d+)*(?:\.\d+)?$
this will validate whatever you like
and at the same time:
not validate:
numbers ending in ,
numbers ending in .
numbers having . before comma
numbers having more than one decimal points
check out the demo here : http://regex101.com/r/zI0mJ4
Your format is a bit strange as it is not a standard format.
My first thought was to put a float instead of a string and put a Range validation attribute to avoid negative number.
But because of formatting, not sure it would work.
Another way is the regex, of course.
The one you propose means :
"some numbers then possibly a group formed by a dot and two numbers exactly".
This is not what you exepected.
Strictly fitted your example of a number lower than 100,000.99 one regex could be :
^[0-9]{1-2}[\.,][0-9]{3}([\.,][0-9]{1-2})?$
A more global regex, that accept all positive numbers is the one posted by Avinash Raj : (?:\d|[,\.])+
I'm completely new in this area, I need a regex that follows these rules:
Only numbers and symbols are allowed.
Must start with a number and ends with a number.
Must not contain more than 1 symbol in a row. (for example 123+-4567 is not accepted but 12+345-67 is accepted.
I tried ^[0-9]*[+-*/][0-9]*$ but I think it's a stupid try.
You were close with your attempt. This one should work.
^[0-9]+([+*/-][0-9]+)*$
explanation:
^ matches beginning of the string
[0-9]+ matches 1 or more digits.
[+*/-] matches one from specified symbols
([+*/-][0-9]+)* matches group of symbol followed by at least one digit, repeated 0 or more times
$ matches end of string
We'll build that one from individual parts and then we'll see how we can be smarter about that:
Numbers
\d+
will match an integer. Not terribly fancy, but we need to start somewhere.
Must start with a number and end with a number:
^\d+.*\d+$
Pretty straightforward. We don't know anything about the part in between, though (also the last \d+ will only match a single digit; we might want to fix that eventually).
Only numbers and symbols are allowed. Depending on the complexity of the rest of the regex this might be easier by explicitly spelling it out or using a negative lookahead to make sure there is no non-(number|symbol) somewhere in the string. I'll go for the latter here because we need that again:
(?!.*[^\d+*/-])
Sticking this to the start of the regex makes sure that the regex won't match if there is any non-(number|symbol) character anywhere in the string. Also note that I put the - at the end of the character class. This is because it has a certain special meaning when used between two other characters in a character class.
Must not contain more than one symbol in a row. This is a variation on the one before. We just make sure that there never is more than one symbol by using a negative lookahead to disallow two in sequence:
(?!.*[+/*-]{2})
Putting it all together:
(?!.*[^\d+*/-])(?!.*[+/*-]{2})^\d+.*\d+$
Testing it:
PS Home:\> '123+-4567' -match '(?!.*[^\d+*/-])(?!.*[+/*-]{2})^\d+.*\d+$'
False
PS Home:\> '123-4567' -match '(?!.*[^\d+*/-])(?!.*[+/*-]{2})^\d+.*\d+$'
True
However, I only literally interpreted your rules. If you're trying to match arithmetic expressions that can have several operands and operators in sequence (but without parentheses), then you can approach that problem differently:
Numbers again
\d+
Operators
[+/*-]
A number followed by an operator
\d+[+/*-]
Using grouping and repetition to match a number followed by any number of repetitions of an operator and another number:
\d+([+/*-]\d+)*
Anchoring it so we match the whole string:
^\d+([+/*-]\d+)*$
Generally, for problems where it works, this latter approach works better and leads to more understandable expressions. The former approach has its merits, but most often only in implementing password policies (apart from »cannot repeat any of your previous 30689 passwords«).