RegEx that matches a string of numbers in a particular format? - regex

I need a regular expression that will tell if a string is in the following format. The groups of numbers must be comma delimited. Can contain a range of numbers separated by a -
300, 200-400, 1, 250-300
The groups can be in any order.
This is what I have so far, but it's not matching the entire string. It's only matching the groups of numbers.
([0-9]{1,3}-?){1,2},?

Try this one:
^(?:\d{1,3}(?:-\d{1,3})?)(?:,\s*\d{1,3}(?:-\d{1,3})?|$)+
Since you didn't specify the number ranges I leave this to you. In any case you should do math with regex :)
Explanation:
"
^ # Assert position at the beginning of the string
(?: # Match the regular expression below
\\d # Match a single digit 0..9
{1,3} # Between one and 3 times, as many times as possible, giving back as needed (greedy)
(?: # Match the regular expression below
- # Match the character “-” literally
\\d # Match a single digit 0..9
{1,3} # Between one and 3 times, as many times as possible, giving back as needed (greedy)
)? # Between zero and one times, as many times as possible, giving back as needed (greedy)
)
(?: # Match the regular expression below
# Match either the regular expression below (attempting the next alternative only if this one fails)
, # Match the character “,” literally
\\s # Match a single character that is a “whitespace character” (spaces, tabs, and line breaks)
* # Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
\\d # Match a single digit 0..9
{1,3} # Between one and 3 times, as many times as possible, giving back as needed (greedy)
(?: # Match the regular expression below
- # Match the character “-” literally
\\d # Match a single digit 0..9
{1,3} # Between one and 3 times, as many times as possible, giving back as needed (greedy)
)? # Between zero and one times, as many times as possible, giving back as needed (greedy)
| # Or match regular expression number 2 below (the entire group fails if this one fails to match)
\$ # Assert position at the end of the string (or before the line break at the end of the string, if any)
)+ # Between one and unlimited times, as many times as possible, giving back as needed (greedy)
"

^(\d+(-\d+)?)(,\s*(\d+(-\d+)?))*$

This should work:
/^([0-9]{1,3}(-[0-9]{1,3})?)(,\s?([0-9]{1,3}(-[0-9]{1,3})?))*$/

You need some repetition:
(?:([0-9]{1,3}-?){1,2},?)+
To ensure that the numbers are correct, i.e. that you don't match numbers like 010, you might want to change the regex slightly. I also changed the range part of the regex, so that you don't match things like 100-200- but only 100 or 100-200, and added support for whitespaces after the comma (optional):
(?:(([1-9]{1}[0-9]{0,2})(-[1-9]{1}[0-9]{0,2})?){1,2},?\s*)+
Also, depending on what you want to capture, you might want to change the capturing brackets () to non capturing ones (?:)
UPDATE
A revised version based on the latest comments:
^\s*(?:(([1-9][0-9]{0,2})(-[1-9][0-9]{0,2})?)(?:,\s*|$))+$

([0-9-]+),\s([0-9-]+),\s([0-9-]+),\s([0-9-]+)

Try this regular expression
^(([0-9]{1,3}-?){1,2},?\s*)+$

Related

Regex for 2 items but with one exclusion

I am building a RegEx that needs to find lines that have either:
DateTime.Now
or
Date.Now
But cannot have the literal "SystemDateTime" on the same line.
I started with this (DateTime\.Now|Date\.Now) but now I am stuck with where to put the "SystemDateTime"
Use this. Assuming you are not using /s modifier(or DOTALL) which takes newline characters under the dot(.)
(?!.*SystemDateTime)(DateTime\.Now|Date\.Now)
(?!.*SystemDateTime) means there is no SystemDateTime in front.
You could use negative lookahead like this:
(?!.*SystemDateTime)\bDate(?:Time)?\.Now\b
/(?!.*SystemDateTime)Date(?:Time)?\.Now/
DEMO
EXPLANATION:
Assert that it is impossible to match the regex below starting at this position (negative lookahead) «(?!.*SystemDateTime)»
Match any single character that is not a line break character «.*»
Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
Match the characters “SystemDateTime” literally «SystemDateTime»
Match the characters “Date” literally «Date»
Match the regular expression below «(?:Time)?»
Between zero and one times, as many times as possible, giving back as needed (greedy) «?»
Match the characters “Time” literally «Time»
Match the character “.” literally «\.»
Match the characters “Now” literally «Now»

Chaning the image url with a regular expression

I have to change a url that looks like
http://my-assets.s3.amazonaws.com/uploads/2011/10/PiaggioBeverly-001-106x106.jpg
into this format
http://my-assets.s3.amazonaws.com/uploads/2011/10/106x106/PiaggioBeverly-001.jpg
I understand I need to create a regular expression pattern that will divide the initial url into three groups:
http://my-assets.s3.amazonaws.com/uploads/
2011/10/
PiaggioBeverly-001-106x106.jpg
and then cut off the resolution string (106x106) from the third group, get rid of the hyphen at the end and move the resolution next to the second. Any idea how to get it done using something like preg_replace?
search this : (.*\/)(\w+-\d+)-(.*?)\.
and replace with : \1\3/\2.
demo here : http://regex101.com/r/fX7gC2
The pattern will be as follow(for input uploads/2011/10/PiaggioBeverly-001-106x106.jpg)
^(.*/)(.+?)(\d+x\d+)(\.jpg)$
And the groups will be holding as follows:
$1 = uploads/2011/10/
$2 = PiaggioBeverly-001-
$3 = 106x106
$4 = .jpg
Now rearrange as per your need. You can check this example from online.
As you have mentioned about preg_replace(), so if its in PHP, you can use preg_match() for this.
<?php
$oldurl = "http://my-assets.s3.amazonaws.com/uploads/2011/10/PiaggioBeverly-001-106x106.jpg";
$newurl = preg_replace('%(.*?)/(\w+)-(\w+)-(\w+)\.(\w+)%sim', '$1/$4/$2-$3.jpg', $oldurl);
echo $newurl;
#http://my-assets.s3.amazonaws.com/uploads/2011/10/106x106/PiaggioBeverly-001.jpg
?>
DEMO
EXPLANATION:
Options: dot matches newline; case insensitive; ^ and $ match at line breaks
Match the regular expression below and capture its match into backreference number 1 «(.*?)»
Match any single character «.*?»
Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
Match the character “/” literally «/»
Match the regular expression below and capture its match into backreference number 2 «(\w+)»
Match a single character that is a “word character” (letters, digits, and underscores) «\w+»
Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
Match the character “-” literally «-»
Match the regular expression below and capture its match into backreference number 3 «(\w+)»
Match a single character that is a “word character” (letters, digits, and underscores) «\w+»
Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
Match the character “-” literally «-»
Match the regular expression below and capture its match into backreference number 4 «(\w+)»
Match a single character that is a “word character” (letters, digits, and underscores) «\w+»
Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
Match the character “.” literally «\.»
Match the regular expression below and capture its match into backreference number 5 «(\w+)»
Match a single character that is a “word character” (letters, digits, and underscores) «\w+»
Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»

How do I display this regex result in javascript?

Regular expressions aren't exactly my strong suit. I got a regex for validating international phone numbers here. The validation bit works for me but I don't understand how I can take the regex result and use it to format the number. My question is how do I figure out, from the regex, what the groupings are that I can use to display?
var intl1RegexObj = /^((\+)?[1-9]{1,2})?([-\s\.])?((\(\d{1,4}\))|\d{1,4})(([-\s\.])?[0-9]{1,12}){1,2}$/;
if (IntlRegexObj.test(businessPhoneValue))
{
var formattedPhoneNumber = businessPhoneValue.replace(IntlRegexObj, "($1)");
// display formatted result
}
After simplifying that mess of a regex:
if (subject.match(/^((?:\+)?[1-9]{1,2})?[\-\s.]?((?:\(\d{1,4}\))|\d{1,4})([\-\s.]?\d{1,12}){1,2}$/)) {
// Successful match
}
There are now only 3 capturing groups.
First one $1 is easy, the country code with an optional +.
Then you have the local area code, basically 1-4 numbers with / without parentheses optionally prefixed by [-\s.]. That's $2
Finally you have your the actual phone number which can be from 1 to 24 numbers, including optional space or dot or minus sign [-\s.]
More detailed explanation:
"
^ # Assert position at the beginning of the string
( # Match the regular expression below and capture its match into backreference number 1
(?: # Match the regular expression below
\+ # Match the character “+” literally
)? # Between zero and one times, as many times as possible, giving back as needed (greedy)
[1-9] # Match a single character in the range between “1” and “9”
{1,2} # Between one and 2 times, as many times as possible, giving back as needed (greedy)
)? # Between zero and one times, as many times as possible, giving back as needed (greedy)
[-\s.] # Match a single character present in the list below
# The character “-”
# A whitespace character (spaces, tabs, line breaks, etc.)
# The character “.”
? # Between zero and one times, as many times as possible, giving back as needed (greedy)
( # Match the regular expression below and capture its match into backreference number 2
# Match either the regular expression below (attempting the next alternative only if this one fails)
(?: # Match the regular expression below
\( # Match the character “(” literally
\d # Match a single digit 0..9
{1,4}# Between one and 4 times, as many times as possible, giving back as needed (greedy)
\) # Match the character “)” literally
)
| # Or match regular expression number 2 below (the entire group fails if this one fails to match)
\d # Match a single digit 0..9
{1,4} # Between one and 4 times, as many times as possible, giving back as needed (greedy)
)
( # Match the regular expression below and capture its match into backreference number 3
[-\s.] # Match a single character present in the list below
# The character “-”
# A whitespace character (spaces, tabs, line breaks, etc.)
# The character “.”
? # Between zero and one times, as many times as possible, giving back as needed (greedy)
\d # Match a single digit 0..9
{1,12} # Between one and 12 times, as many times as possible, giving back as needed (greedy)
){1,2} # Between one and 2 times, as many times as possible, giving back as needed (greedy)
$ # Assert position at the end of the string (or before the line break at the end of the string, if any)
"
This regex is whoefully inadequate. As I go to your link, even a couple of the ones listed in non-match will match with this regex. The regex is purely an overlap of possibilities by the look of the groupings that happen to be capture groupings. And any sense of parsing out real parts of the number are sadly destroyed with this regex.
Expanded, it looks like this:
^
(
(\+)?
[1-9]{1,2}
)?
([-\s\.])?
(
(
\(\d{1,4}\)
)
|
\d{1,4}
)
(
([-\s\.])?
[0-9]{1,12}
){1,2}
$
I even tried to forumulate a proper capture grouping for its parts and sadly it shows the problems.
^
(?: \+ )?
( [1-9]{1,2} |) # Capt Group 1, international code (or not)
(?| # Branch Reset
\( (\d{1,4}) \) # Capure Group 2, area code
| (\d{1,4})
)
(?:[-\s.])?
( # Capt Group 3, the rest ########-########
[0-9]{1,12}
[-\s.]?
[0-9]{1,12}?
)
$
There might be something better out there, but this is just a validation wonder that doesen't really work correctly for the most part to do even that.
Regular expressions are not used to format anything. They just tell you if the string you are validating abides by the regular expression's rules. Example would be in a form where a user is entering a phone number. If the string they enter into the form doesn't match the regular expression then the form's validation which uses the regular expression to check the string will say something like, "Phone number is not in correct format."

Need regular expression to validate username

Need a regular expression to validate username which:
should allow trailing spaces but not spaces in between characters
must contain at least one letter,may contain letters and numbers
7-15 characters max(alphanumeric)
cannot contain special characters
underscore is allowed
Not sure how to do this. Any help is appreciated. Thank you.
This is what I was using but it allows space between characters
"(?=.*[a-zA-Z])[a-zA-Z0-9_]{1}[_a-zA-Z0-9\\s]{6,14}"
Example: user name
No spaces are allowed in user name
Try this:
foundMatch = Regex.IsMatch(subjectString, #"^(?=.*[a-z])\w{7,15}\s*$", RegexOptions.IgnoreCase);
Is also allows the use of _ since you allowed this in your attempt.
So basically I use three rules. One to check if at least one letter exists.
Another to check if the string consists only of alphas plus the _ and finally I accept trailing spaces and at least 7 with a max of 15 alpha's. You are in a good track. Keep it up and you will be answering questions here too :)
Breakdown:
"
^ # Assert position at the beginning of the string
(?= # Assert that the regex below can be matched, starting at this position (positive lookahead)
. # Match any single character that is not a line break character
* # Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
[a-z] # Match a single character in the range between “a” and “z”
)
\w # Match a single character that is a “word character” (letters, digits, etc.)
{7,15} # Between 7 and 15 times, as many times as possible, giving back as needed (greedy)
\s # Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
* # Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
$ # Assert position at the end of the string (or before the line break at the end of the string, if any)
"

Regex to match sloppy fractions / mixed numbers

I have a series of text that contains mixed numbers (ie: a whole part and a fractional part). The problem is that the text is full of human-coded sloppiness:
The whole part may or may not exist (ex: "10")
The fractional part may or may not exist (ex: "1/3")
The two parts may be separated by spaces and/or a hyphens (ex: "10 1/3", "10-1/3", "10 - 1/3").
The fraction itself may or may not have spaces between the number and the slash (ex: "1 /3", "1/ 3", "1 / 3").
There may be other text after the fraction that needs to be ignored
I need a regex that can parse these elements so that I can create a proper number out of this mess.
Here's a regex that will handle all of the data I can throw at it:
(\d++(?! */))? *-? *(?:(\d+) */ *(\d+))?.*$
This will put the digits into the following groups:
The whole part of the mixed number, if it exists
The numerator, if a fraction exits
The denominator, if a fraction exists
Also, here's the RegexBuddy explanation for the elements (which helped me immensely when constructing it):
Match the regular expression below and capture its match into backreference number 1 «(\d++(?! */))?»
Between zero and one times, as many times as possible, giving back as needed (greedy) «?»
Match a single digit 0..9 «\d++»
Between one and unlimited times, as many times as possible, without giving back (possessive) «++»
Assert that it is impossible to match the regex below starting at this position (negative lookahead) «(?! */)»
Match the character “ ” literally « *»
Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
Match the character “/” literally «/»
Match the character “ ” literally « *»
Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
Match the character “-” literally «-?»
Between zero and one times, as many times as possible, giving back as needed (greedy) «?»
Match the character “ ” literally « *»
Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
Match the regular expression below «(?:(\d+) */ *(\d+))?»
Between zero and one times, as many times as possible, giving back as needed (greedy) «?»
Match the regular expression below and capture its match into backreference number 2 «(\d+)»
Match a single digit 0..9 «\d+»
Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
Match the character “ ” literally « *»
Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
Match the character “/” literally «/»
Match the character “ ” literally « *»
Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
Match the regular expression below and capture its match into backreference number 3 «(\d+)»
Match a single digit 0..9 «\d+»
Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
Match any single character that is not a line break character «.*»
Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
Assert position at the end of the string (or before the line break at the end of the string, if any) «$»
I think it may be easier to tackle the different cases (full mixed, fraction only, number only) separately from each other. For example:
sub parse_mixed {
my($mixed) = #_;
if($mixed =~ /^ *(\d+)[- ]+(\d+) *\/ *(\d)+(\D.*)?$/) {
return $1+$2/$3;
} elsif($mixed =~ /^ *(\d+) *\/ *(\d+)(\D.*)?$/) {
return $1/$2;
} elsif($mixed =~ /^ *(\d+)(\D.*)?$/) {
return $1;
}
}
print parse_mixed("10"), "\n";
print parse_mixed("1/3"), "\n";
print parse_mixed("1 / 3"), "\n";
print parse_mixed("10 1/3"), "\n";
print parse_mixed("10-1/3"), "\n";
print parse_mixed("10 - 1/3"), "\n";
If you are using Perl 5.10, this is how I would write it.
m{
^
\s* # skip leading spaces
(?'whole'
\d++
(?! \s*[\/] ) # there should not be a slash immediately following a whole number
)
\s*
(?: # the rest should fail or succeed as a group
-? # ignore possible neg sign
\s*
(?'numerator'
\d+
)
\s*
[\/]
\s*
(?'denominator'
\d+
)
)?
}x
Then you can access the values from the %+ variable like this:
$+{whole};
$+{numerator};
$+{denominator};