Phone number regex - Merge three conditions - javascript

I need to create a regex function which will validate a phone number field based on certain conditions and show alerts for each of the three cases.
Practically I have this 3 regex functions which I want to combine in a single one.
/^3\d{9}$/; //If it starts with 3 and has another 9 numbers it's a cellphone
/^0\d{7,10}$/; //If it starts with 0 and has another 7-10 numbers it's a landline
/^(?:00|\+)/; //If it starts with 00 or a + sign, it's an international number
What I am trying to achieve, is to have a javascript function which will combine this three regex functions and show a certain message in case the number is not valid.
So for example if the number starts with 3 but it has less or more than 9 numbers after the 3, probably it's a wrong cellphone number so I want to warn the user about that. Same thing for the Landline. For the international numbers I simply want to make them aware that it might be an international number because it starts with double 00 or + sign.
My problem is that I don't know how to combine this three regex values in a single one, which will allow me to build a simple and clean javascript code.

I think this will work for you: /^(?:3\d{9}|0\d{7,10}|(?:00|\+)\d+)$/g
const testPhoneNumber = number => /^(?:3\d{9}|0\d{7,10}|(?:00|\+)\d+)$/.test(number)
const numbers = [123, "+48667065144", 3111222333, "001234567", "00123456879", 6473812354, 3475456389, 7483925821]
for (const number of numbers) {
console.log(`${number} is ${testPhoneNumber(number) ? "valid": "not valid"} phone number`)
}

match(/(^3\d{9}$)|(^0\d{7,10}$)|(^(?:00|\+))/)
this will capture the matched data in an array (size 4).
position 0 : the matched data
position 1 : matched data of the 1st regexp
....

function check(number) {
//var number = '3123456789';
//var number = '01234567';
//var number = '001';
var regexList = [
'^3\\d{9}$', //If it starts with 3 and has another 9 numbers it's a cellphone
'^0\\d{7,10}$', //If it starts with 0 and has another 7-10 numbers it's a landline
'^[0]{2}|[\+]' //If it starts with 00 or a + sign, it's an international number
];
for (var r in regexList)
if (number.match(new RegExp(regexList[r])))
break;
else
r = null;
switch (r) {
case "0":
alert('If it starts with 3 and has another 9 numbers it\'s a cellphone');
break;
case "1":
alert('If it starts with 0 and has another 7-10 numbers it\'s a landline');
break;
case "2":
alert('If it starts with 00 or a + sign, it\'s an international number');
break;
default:
alert('Invalid number');
}
}
<input type="text" id="numberToCheck" />
<input type="button" onclick="check(document.getElementById('numberToCheck').value)" />

As "elegant" as I can make it...
var input = '00372553253';
var matches = [];
// The following is technically one line!
[
{regex: /^3\d{9}$/, type: "cellphone"},
{regex: /^0\d{7,10}$/, type: "landline"},
{regex: /^(?:00|\+)/, type: "international"}
].forEach(
function(element) {
if (element.regex.test(input))
matches.push(element.type);
}
);
alert(matches);
The test case will actually match two regexes!

Related

How to check if number ends in .99

I'm attempting to do some validation a price field. I would like to check if the price entered into the price field ends in .99
I've attempted find posts about this but I can't find examples for decimal numbers only whole numbers. I tried to check by doing price % 1 but it isnt consistent as the price increases by 10, 20 etc.
Is there a quick way to check if all numbers end in .99?
const price = 9.99
console.log(price % 1)
Floating point math is inherently imprecise. The actual mathematical expression price - 9 will get those extra 0s and a 2 too.
Best you could do is convert to a string with fixed precision (rounding off any extraneous precision; for a price in dollars, you'd only need two digits, but you might go to three or more to verify the price entered didn't end with nonsense fractions of a cent) and perform a string test, e.g.
price.toFixed(2).endsWith('.99')
which doesn't try to perform math on price at all, it just rounds off to two digits after the decimal place to produce a string, then checks if the string ends with .99.
You can try regular expression as well. See following code for example:
function testRegex() {
var re = /^[0-9]*[.](99)$/;
var val = document.getElementById("inputValue").value;
if(re.exec(val)) {
document.getElementById("result").innerText = "Found match!!!";
} else {
document.getElementById("result").innerText = "Found no match!!!";
}
}
<input type="text" id="inputValue" value="" onkeyup="testRegex()" />
<div id="result"></div>
You can perform that validation using the following regular expression:
/\.99$/
First, we try to match an explicit . by escaping it with a backlash. Then, the next two characters must be 99, and then the string end must occur for the successful match. We check that with $. For example,
prices = [0.99, 0.0099, 1.99, 2.99, 3.98, 4.01];
for (const price of prices) {
if (/\.99$/.test(price.toString())) {
console.log(`${price} ends with .99`);
}
}
will print:
0.99 ends with .99
1.99 ends with .99
2.99 ends with .99

How to make regular expression only accept special formula?

I'm making html page for special formula using angularJS.
<input ng-model="expression" type="text" ng-blur="checkFormula()" />
function checkFormula() {
let regex;
if (scope.formulaType === "sum") {
regex = "need sum regular expression here"; // input only like as 1, 2, 5:6, 8,9
} else {
regex = "need arithmetic regular expression here"; // input only like as 3 + 4 + 6 - 9
}
if (!regex.test(scope.expression)) {
// show notification error
Notification.error("Please input expression correctly");
return;
}
// success case
if (scope.formulaType === "sum") {
let fields = expression.split(',');
let result = fields.reduce((acc, cur) => { return acc + Number(cur) }, 0);
// processing result
} else {
// need to get fields with + and - sign.
// TODO: need coding more...
let result = 0;
// processing result
}
}
So I want to make inputbox only accept my formula.
Formulas are two cases.
1,2,3:7,9
or
4-3+1+5
First case, means sum(1,2,3,4,5,6,7,9) and second case means (4-3+1+5).
But I don't know regular expression how to process it.
I searched google, but I didn't get result for my case.
So I want to need 2 regex match.
1,2,3:7,9
Fot this pattern, you can try this one:
^\d+(?::\d+)?(?:,\d+(?::\d+)?)*$
^\d+(?::\d+)?
matches string starts with a number(e.g. 1) or two numbers separated by a column (e.g. 1:2)
(?:,\d+(?::\d+)?)*$
repeats the previous pattern with a comma in front of it as many time as possible until meets the end of the string (e.g. ,2:3,4:5,6)
4-3+1+5
Fot this pattern, you can try this one:
^\d+(?:[+-]\d+)*$
Like the previous one, this is much simpler
^\d+
starts with a number(e.g. 12)
(?:[+-]\d+)*$
repeats the previous pattern with a - or + in front of it as many time as possible until meets the end of the string (e.g. +2-3+14)
Also, if you need at least one pair of numbers.
Such as 1,2 is allowed but just 1 is not. You can just change the * before $ to +:
^\d+(?::\d+)?(?:,\d+(?::\d+)?)+$
^\d+(?:[+-]\d+)+$
And if you allow white spaces in between them:
^\d+(?:\s*:\s*\d+)?(?:\s*,\s*\d+(?:\s*:\s*\d+)?)+$
^\d+(?:\s*[+-]\s*\d+)+$

how to detect mobile numbers in a string using javascript

To be honest, this sound like a duplicate post, but this is totally different from other post.
I'm building a chat room, where i would like to detect mobile number in user sending messages and warn the users that sending mobile numbers in the chat room is not safe and its against our policy.
There are few posts shows how to detect US number. But what about Indian numbers? they are 10 digit numbers.
var input = "hey im emily, call me now 9876543210"
I have to detect the number in all these formats.
9876543210
9 8 7 6 5 4 3 2 1 0
98765 43210
+919876543210
+91 9876543210
Some smart users always comes up with a smart way to come around those filters used in the client side javascript. So i have to be well prepared to detect all the method they use.
Example Message :
"hey this is emy, call me now 9876543210"
Expected output : pop up saying, hey buddy, sending numbers in the room is not safe and not allowed here.
Note: The string message should be allowed to send upoto 5 digit numbers, without getting the alert pop up. Or if you have any better idea? suggest me and we can make it work. Thanks
Here's a regex for a 7 or 10 digit number, with extensions allowed, delimiters are spaces, dashes, or periods:
^(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$
Although you need to add conditions for special numbers like 911, 100, 101
In your test cases the length of phone number is 10:
So try the following code:
let input = "hey im emily, call me now 9 876543210";
let matched = input.match(/\d+/g).join('');
let phoneNumberLength = 10;
if (matched.length >= phoneNumberLength) {
console.log(`we've found a phone number. The number is ${matched}`);
} else
console.log(`The message does not contain phone number`);
Try to adjust this code as it is desired
UPDATE:
This code is intended to get desired results with test case by #tibetty:
let input = 'hi dude, please call my cell phone +86 13601108486 at 300pm"'
let matched = input.split(' ');
let maxIndex = matched.length - 1;
let filtered = matched.filter((s, i) => {
if (i != maxIndex && isNumeric(s) && isNumeric(matched[i + 1]))
return true;
if (isNumeric(s))
return true;
return false;
});
console.log(` The number is found ${filtered.join(' ')}`);
function isNumeric(n) {
return n.match(/^(?:[+\d].*\d|\d)$/);
}
try this one:
https://www.w3resource.com/javascript/form/phone-no-validation.php
function phonenumber(inputtxt)
{
var phoneno = /^\d{10}$/;
if((inputtxt.value.match(phoneno))
{
return true;
}
else
{
alert("message");
return false;
}
}

how to generate unique ID character using letters a-z

Here is a little challenge, I hope it will be useful for others too.
Task is to obtain an ID character from alphabets of english language. a-to-z
My solution currently allows ID (words) of 26 diff length (max possible). with 90 possible words.
I know this can be increased if we pick random characters after single character IDs are obtained (done with.) (But) I am finding it hard to figure out how to manage NOT hitting a combination already found (ID has to be unique). As we see it takes a long time if it starts finding the same combinations over and over. this probability increases as we obtain more and more ID-combinations.
Here is my code and fiddle to test and check:
fiddle
code:
html
<p>
start
</p>
jquery:
function addto(t) {
$("p").append("<b>" + t + "</b>");
}
global_ID_array = [];
lowerAlpha = "abcdefghijklmnopqrstuvwxyz";
var myIDlength = 1;
function getIDChar (){
do {
var myIDchar = lowerAlpha.substr(0, myIDlength);
lowerAlpha = lowerAlpha.replace(myIDchar,'');
if (lowerAlpha.length < myIDlength){
lowerAlpha = "abcdefghijklmnopqrstuvwxyz"; //reset
myIDlength++;
}
} while (global_ID_array.indexOf(myIDchar) > -1)
global_ID_array.push(myIDchar);
addto(myIDlength+':'+global_ID_array.length+',');
}
do{
getIDChar();
}while (myIDlength < 26);
addto('<br \>myIDlength='+myIDlength);
addto('<br \>global_ID_array last val='+global_ID_array[global_ID_array.length-1]+'<p>');
To get started, instead of thinking about the IDs in terms of letters, think about it in terms of numbers.
Since there are 26 possible characters, each character can be considered as a digit of a base-26 numeric system, with a == 0, and z == 25. The problem now boils down to generating a number and converting it to base-26 using the alphabets as digits. Since the ID length is 26 characters, we can generate up to 26^26 unique IDs.
Now, to make sure that the ID generated is unique (up to 26^26 generated IDs), we need to find a way to generate a unique number every time. The simplest way to do this is to initialize a counter at 0 and use it to generate the ID. Every time an ID is done generating, increment the counter. Of course, this is a very deterministic generation algorithm, but you could use a seeded random number generator that guarantees the uniqueness of random numbers generated in a range.
The algorithm may look as follows:
n = random(0, 26^26 - 1)
id = "a" * 26
// chars[i] is the character representing the base-26 digit i;
// you may change/shuffle the list as you please
chars = ['a', 'b', 'c', ..., 'y', 'z']
for i in 0..26 {
// Get the character corresponding to the next base-26 digit of n (n % 26)
id[26 - i] = chars[n % 26]
n /= 26
}

JavaScript regex: capturing optional groups while having a strict matching

I am trying to extract some data from user input that should follow this format: 1d 5h 30m, which means the user is entering an amount of time of 1 day, 5 hours and 30 minutes.
I am trying to extract the value of each part of the input. However, each group is optional, meaning that 2h 20m is a valid input.
I am trying to be flexible in the input (in the sense that not all parts need to be input) but at the same time I don't watch my regex to match some random imput like asdfasdf20m. This one should be rejected (no match).
So first I am getting rid of any separator the user might have used (their input can look like 4h, 10m and that's ok):
input = input.replace(/[\s.,;_|#-]+/g, '');
Then I am capturing each part, which I indicate as optional using ?:
var match = /^((\d+)d)?((\d+)h)?((\d+)m)?$/.exec(input);
It is kind of messy capturing an entire group including the letter when I only want the actual value, but I cannot say that cluster is optional without wrapping it with parentheses right?
Then, when an empty group is captured its value in match is undefined. Is there any function to default undefined values to a particular value? For example, 0 would be handy here.
An example where input is "4d, 20h, 55m", and the match result is:
["4d20h55m", "4d", "4", "20h", "20", "55m", "55", index: 0, input: "4d20h55m"]
My main issues are:
How can I indicate a group as optional but avoid capturing it?
How can I deal with input that can potentially match, like abcdefg6d8m?
How can I deal with an altered order? For example, the user could input 20m 10h.
When I'm asking "how to deal with x" I mean I'd like to be able to reject those matches.
As variant:
HTML:
<input type="text">
<button>Check</button>
<div id="res"></div>
JS:
var r = [];
document.querySelector('button').addEventListener('click', function(){
var v = document.querySelector('input').value;
v.replace(/(\d+d)|(\d+h)|(\d+m)/ig, replacer);
document.querySelector('#res').innerText = r;
}, false);
function trim(s, mask) {
while (~mask.indexOf(s[0])) {
s = s.slice(1);
}
while (~mask.indexOf(s[s.length - 1])) {
s = s.slice(0, -1);
}
return s;
}
function replacer(str){
if(/d$/gi.test(str)){
r[0] = str;
}
else if(/h$/gi.test(str)){
r[1] = str;
}
else if(/m$/gi.test(str)){
r[2] = str;
}
return trim(r.join(', '), ',');
}
See here.

Categories

Resources