Possible to make regular expression with sub-query - javascript

I am trying to write a regular expression for a bit of javascript code that takes a user's input of a mobile number and in one regular expression, performs the following checks:
Starts with 07
Contains only numbers, whitespace or dashes
Contains exactly 11 numbers
Is this possible to do in just one regular expression and if so, how please?

I don't think it is possible with one regex, but it is possible by testing for two conditions:
if(/^07[\d\- ]+$/.test(str) && str.replace(/[^\d]/g, "").length === 11) {
//string matches conditions
}
Explanation of the regex:
^: Anchor that means "match start of string".
07: Match the string 07. Together with the above, it means that the string must start with 07.
[: Beginning of a character class i.e., a set of characters that we want to allow
\d: Match a digit (equivalent to 0-9).
\-:
" ": Match whitespace (markdown doesn't let me show a single space as code)
]: End of character class.
+: One or more of the previous.
$: Anchor that means "match end of string". Together with the ^, this basically means that this regex must apply to the entire string.
So here we check to see that the string matches the general format (starts with 07 and contains only digits, dashes or spaces) and we also make sure that we have 11 numbers in total inside the string. We do this by getting of anything that is not a digit and then checking to see that the length of the string is equal to 11.

Since #Vivin throws out the challenge :
/^07([-\s]*\d){9}[-\s]*$/
^07 : begin with digits 07
( : start group
[-\s]* : any number of - or whitespace
\d : exactly one digit
){9} : exactly 9 copies of this group (11 digits including 07)
[-\s]* : optional trailing spaces or -
$ : end of string
Of course a more useful way might be as follows
if ((telNo = telNo.replace (/[-\s]+/g, '')).match (/^07\d{9}$/)) {
....
}
which has the advantage (?) of leaving just the digits in telNo

Thank you all for trying, but after a good while trying different ideas, I finally found a working "single" regular expression:
07((?:\s|-)*\d(?:\s|-)*){9}
This make sure that it starts with 07, only contains digits, whitespace or dashes, and only 11 of them (9 plus the first 2) are numbers.
Sorry to have wasted your time.
Explanation:
() - include in capture
(?:) - do not include in capture
\s - whitespace
| - or
- - dash
* - zero or more
\d - digits only
{9} - exactly nine of what is captured

Related

Javascript regex to make sure that string matches format x:y

I am trying to parse a string which has two numbers, both can be between 1 and 3 digits, and will have a colon in between. Here are some examples:
"1:1"
"1:12"
"12:1"
"123:12"
Also, the given string may also be invalid, and I need to detect if it is. My attempts so far to make sure the string is valid have looked like this: .match(/[1-9]\:[1-9]/);. But then I noticed that this wont work if a string such as this is inputted: "characters12:4characters". How would I go about validating the string to make sure it is in the format x:y?
Any help would be deeply appreciated.
Edit: numbers which contain 0 at the beginning is valid, but may not be given.
You may use
/^\d{1,3}:\d{1,3}$/
See the regex demo
Details
^ - start of a string
\d{1,3} - one, two or three digits (\d is a shorthand character class that matches any digit (it can also be written as a [0-9] character class) and {1,3} is a limited quantifier that matches1 to 3 consecutive occurrences of the quantified subpattern)
: - a colon
\d{1,3} - one, two or three digits
$ - end of the string.

Need to understand some regular expression [duplicate]

This question already has an answer here:
Reference - What does this regex mean?
(1 answer)
Closed 8 years ago.
I have a regular expression in a code(written by someone else), I am trying to understand what that expression means.
var decimal = /^\d[0,1]+(\.\d[1,4])?$/;
Can anyone explain to me what it does...
In order:
^ - Match the beginning of the input
\d - A digit (0-9)
[0,1]+ - One or more occurrences of the characters 0, ,, or 1 —but see note below, this is probably not what the author meant to do
( - The beginning of a capture group
\. - A literal . (without the backslash, it would mean something special)
\d - A digit
[1,4] - Exactly one of the characters 1, ,, or 4 —but see note below, this is probably not what the author meant to do
) - The end of the capture group
? - Inidicates that the entire capture gruop is optional (zero or once)
$ - Match the end of the input
Re the [0,1]+ and [1,4], the expression was probably supposed to have {0,1} and {1,4} instead, which mean:
{0,1} - match what came before either zero times or once (note that you have to remove the + that was after the [0,1])
{1,4} - match what came before 1, 2, 3, or 4 times
Here's an explanation on regex101.com
If we speculate that they probably meant this
/^\d{0,1}(\.\d{1,4})?$/
...then in prose it means: Match any number that may or may not have one leading digit, and then may or may not have a decimal point followed by one to four digits. But it's still got issues, not least that the string "" matches it, and (depending on what you're doing) you probably want to support values equal to or greater than 2, which that expression doesn't.
Basically: If it's meant to validate a decimal, throw it away, and search for something that does a better job, such as this if you really want at most four digits of precision and you want to capture the fractional portion (as your original does):
/^(?:0|[1-9]\d*)(\.\d{1,4})?$/
If you want to allow any level of precision:
/^(?:0|[1-9]\d*)(\.\d+)?$/
If you don't need the capture group:
/^(?:0|[1-9]\d*)(?:\.\d{1,4})?$/ // Only allow 1-4 digits of precision
/^(?:0|[1-9]\d*)(?:\.\d+)?$/ // Allow any number of digits of precision
That last is probably what I'd go with. Note that it doesn't allow leading zeros you wouldn't normally write (e.g., it disallows 02.345). If you want to allow them, then just /^\d*(?:\.\d+)?$/.
The crucial parts:
^: Beginning of input
\d: A digit
[0,1]+: One or more occurences of 0 or 1 or ,
(\.\d[1,4])?: An optional capture group, containing: a . literal, a digit, and a 1 or 4 or ,
$: End of input
The full story can be found here.
So some allowed input is:
80.94
41111111.44
4,,,1.44
30

regex allows one character (it should not) why?

Hello I am trying to create a regex that recognizes money and numbers being inputted. I have to allow numbers because I am expecting non-formatted numbers to be inputted programmatically and then I will format them myself. For some reason my regex is allowing a one letter character as a possible input.
[\$]?[0-9,]*\.[0-9][0-9]
I understand that my regex accepts the case where multiple commas are added and also needs two digit after the decimal point. I have had an idea of how to fix that already. I have narrowed it down to possibly the *\. as the problem
EDIT
I found the regex expression that worked [\$]?([0-9,])*[\.][0-9]{2} but I still don't know how or why it was failing in the first place
I am using the .formatCurrency() to format the input into a money format. It can be found here but it still allows me to use alpha characters so i have to further masked it using the $(this).inputmask('Regex', { regex: "[\$]?([0-9,])*[\.][0-9]{2}" }); where input mask is found here and $(this) is a reference to a input element of type text. My code would look something like this
<input type="text" id="123" data-Money="true">
//in the script
.find("input").each(function () {
if ($(this).attr("data-Money") == "true") {
$(this).inputmask('Regex', { regex: "[\$]?([0-9,])*[\.][0-9]{2}" });
$(this).on("blur", function () {
$(this).formatCurrency();
});
I hope this helps. I try creating a JSfiddle but Idk how to add external libraries/plugin/extension
The "regular expression" you're using in your example script isn't a RegExp:
$(this).inputmask('Regex', { regex: "[\$]?([0-9,])*[\.][0-9]{2}" });
Rather, it's a String which contains a pattern which at some point is being converted into a true RegExp by your library using something along the lines of
var RE=!(value instanceof RegExp) ? new RegExp(value) : value;
Within Strings a backslash \ is used to represent special characters, like \n to represent a new-line. Adding a backslash to the beginning of a period, i.e. \., does nothing as there is no need to "escape" the period.
Thus, the RegExp being created from your String isn't seeing the backslash at all.
Instead of providing a String as your regular expression, use JavaScript's literal regular expression delimiters.
So rather than:
$(this).inputmask('Regex', { regex: "[\$]?([0-9,])*[\.][0-9]{2}" });
use
$(this).inputmask('Regex', { regex: /[\$]?([0-9,])*[\.][0-9]{2}/ });
And I believe your "regular expression" will perform as you expect.
(Note the use of forward slashes / to delimit your pattern, which JavaScript will use to provide a true RegExp.)
Firstly, you can replace '[0-9]' with '\d'. So we can rewrite your first regex a little more cleanly as
\$?[\d,]*\.\d\d
Breaking this down:
\$? - A literal dollar sign, zero or one
[\d,]* - Either a digit or a comma, zero or more
\. - A literal dot, required
\d - A digit, required
\d - A digit, required
From this, we can see that the minimum legal string is \.\d\d, three characters long. The regex you gave will never validate against any one character string.
Looking at your second regex,
[\$]? - A literal dollar sign, zero or one
([0-9,])* - Either a digit or a comma, subexpression for later use, zero or more
[\.] - A literal dot, required
[0-9]{2} - A digit, twice required
This has the exact same minimum matchable string as above - \.\d\d.
edit: As mentioned, depending on the language you may need to escape forward slashes to ensure they aren't misinterpretted by the language when processing the string.
Also, as an aside, the below regex is probably closer to what you need.
[A-Z]{3} ?(\d{0,3}(?:([,. ])\d{3}(?:\2\d{3})*)?)(?!\2)[,.](\d\d)\b
Explanation:
[A-Z]{3} - Three letters; for an ISO currency code
? - A space, zero or more; for readability
( - Capture block; to catch the integer currency amount
\d{0,3} - A digit, between one and three; for the first digit block
(?: - Non capturing block (NC)
([,. ]) - A comma, dot or space; as a thousands delimiter
\d{3} - A digit, three; the first possible whole thousands
(?: - Non capturing block (NC)
\2 - Match 2; the captured thousands delimiter above
\d{3} - A digits, three
)* - The above group, zero or more, i.e. as many thousands as we want
)? - The above (NC) group, zero or one, ie. all whole thousands
) - The above group, i.e everything before the decimal
[.,] - A comma or dot, as a decimal delimiter
(\d{2}) - Capture, A digit, two; ie. the decimal portion
\b - A word boundry; to ensure that we don't catch another
digit in the wrong place.
The negative lookahead was provided by an answer from John Kugelman in this question.
This correctly matches (matches enclosed in square brackets):
[AUD 1.00]
[USD 1,300,000.00]
[YEN 200 000.00]
I need [USD 1,000,000.00], all in non-sequential bills.
But not:
GBP 1.000
YEN 200,000

Regex string match?

I have a long string in javascript like
var string = 'abc234832748374asdf7943278934haskhjd';
I am trying to match like
abc234832748374 - that is - I have tried like
string.match(\abc[^abc]|\def[^def]|) but that doesnt get me both strings because I need numbers after them ?
Basically I need abc + 8 chars after and def the 8-11 chars after ? How can I do this ?
If you want the literal strings abc or def followed by 8-11 digits, you need something like:
(abc|def)[0-9]{8,11}
You can test it here: http://www.regular-expressions.info/javascriptexample.html
Be aware that, if you don't want to match more than 11 digits, you will require an anchor (or [^0-9]) at the end of the string. If it's just 8 or more, you can replace {8,11} with {8}.
To elaborate on an already posted answer, you need a global match, as follows:
var matches = string.match(/(abc|def)\d{8,11}/g);
This will match all subsets of the string which:
Start with "abc" or "def". This is the "(abc|def)" portion
Are then followed by 8-11 digits. This is the "\d{8,11}" portion. \d matches digits.
The "g" flag (global) gets you a list of all matches, rather than just the first one.
In your question, you asked for 8-11 characters rather than digits. If it doesn't matter whether they are digits or other characters, you can use "." instead of "\d".
I also notice that each of your example matches have more than 11 characters following the "abc" or "def". If any number of digits will do, then the following regex's may be better suited:
Any number of digits - var matches = string.match(/(abc|def)\d*/g);
At least one digit - var matches = string.match(/(abc|def)\d+/g);
At least 8 digits - var matches = string.match(/(abc|def)\d{8,}/g);
You can match abc[0-9]{8} for the string abc followed by 8 digits.
If the first three characters are arbitrary, and 8-11 digits after that, try [a-z]{3}[0-9]{8,11}
Use the below regex to get the exact match,
string.match(/(abc|def)\d{8,11}/g);
Ends with g
"g" for global
"i" for ignoreCase
"m" for multiline

Regular expression for number with length of 4, 5 or 6

I need a regular expression that validate for a number with length 4, 5, 6
I used ^[0-9]{4} to validate for a number of 4, but I do not know how to include validation for 5 and 6.
Try this:
^[0-9]{4,6}$
{4,6} = between 4 and 6 characters, inclusive.
[0-9]{4,6} can be shortened to \d{4,6}
Be aware that, as written, Peter's solution will "accept" 0000. If you want to validate numbers between 1000 and 999999, then that is another problem :-)
^[1-9][0-9]{3,5}$
for example will block inserting 0 at the beginning of the string.
If you want to accept 0 padding, but only up to a lengh of 6, so that 001000 is valid, then it becomes more complex. If we use look-ahead then we can write something like
^(?=[0-9]{4,6}$)0*[1-9][0-9]{3,}$
This first checks if the string is long 4-6 (?=[0-9]{4,6}$), then skips the 0s 0*and search for a non-zero [1-9] followed by at least 3 digits [0-9]{3,}.
If the language you use accepts {}, you can use [0-9]{4,6}.
If not, you'll have to use [0-9][0-9][0-9][0-9][0-9]?[0-9]?.
To match standalone 4-6-digit numbers, you may use
^\d{4,6}$ // If full string match is expected
\b\d{4,6}\b // If no letters/digits/underscores are expected on both ends
(?<!\d)\d{4,6}(?!\d) // If no digits are expected on both ends, but letters/_ are allowed
(^|\D)(\d{4,6})(?!\d) // Same as above, in case lookbehinds are not supported (get Group 2 value)
See Regex #1 - Regex #2 - Regex #3 and Regex #4 demos.
Details:
^ - start of string
\b - a word boundary
(?<!\d) - a negative lookbehind that fails the match if there is a digit immediately to the left of the current location
(^|\D) - a capturing group matching either start of string or a non-digit char
\d{4,6} - four, five or six digits
(?!\d) - a negative lookahead that fails the match if there is a digit immediately to the right of the current location
$ - end of string

Categories

Resources