I'm very new to regex, reading and learning but need some direction
I need to parse email addresses for quality
fax=1AreaCodeNumber#domain.com
or 1AreaCodeNumber#doamin.com
need to ensure the 1AreaCodeNumber is 10 digits only, must start with 1
If it is 9 digits, and the first number is not a 1 add the 1.
Any help would be greatly appreciated.
Javascript:
const regex = /^(1?)\d{9}#(domain\.com|doamin\.com)/;
str = `1123456879#domain.com`;
let m;
if ((m = regex.exec(str)) !== null) {
// The result can be accessed through the `m`-variable.
if(m[1] === '') {
str = '1' + str;
}
console.log('matched: ' + str);
} else {
console.log('No Match');
}
1?\d{9} will match a 1 followed by 9 digits, or 9 digits without the 1. The full regex would be (fax=)?1?\d{9}#domain.com
Related
I'm trying to find numbers that start and end with the same digit and have similar numbers in between the two digits. Here are some examples:
7007 1551 3993 5115 9889
I tried the following regular expression to identify the first and the last digit. However, no number was selected.
^(\d{1})\1$
I appreciate your help.
Use this:
(\d)(\d)\2+\1
Capture the first and second digits separately, then match them in the reverse order.
Demo
Maybe,
^(\d)(\d)\2+\1$
might be an option to look into.
RegEx Demo
If you wish to simplify/update/explore the expression, it's been explained on the top right panel of regex101.com. You can watch the matching steps or modify them in this debugger link, if you'd be interested. The debugger demonstrates that how a RegEx engine might step by step consume some sample input strings and would perform the matching process.
Your regex will match two digit numbers where both digits are the same. You just need to expand it: (\d)(\d)\2\1
As well, since the numbers are on the same line, use word boundaries (\b) instead of line boundaries (^ and $).
\b(\d)(\d)\2\1\b
BTW {1} is redundant
Demo on regex101
Simple JS way.
let a = "7007 1551 3393 5115 9883";
a = a.split(" ");
let ans = [];
a.forEach((val) => {
let temp = val.split("");
if (temp && temp[0] === temp[temp.length - 1]) {
temp = temp.slice(1,temp.length-1);
ans.push(temp.slice(0,temp.length).every( (val, i, arr) => val === arr[0] )) ;
} else {
ans.push(false);
}
});
console.log(ans);
Regular Expression:
let a = "7007 1551 3393 5115 9883";
a = a.split(" ");
let ans = [];
a.forEach((val) => {
let reg = /(\d)(\d*)(\d)/gi;
let match = reg.exec(val);
if (match && match.length > 3 && match[1] === match[3]) {
let temp = match[2];
temp = temp.split("");
temp = temp.slice(0,temp.length);
ans.push(temp.every( (val, i, arr) => val === arr[0] )) ;
} else {
ans.push(false);
}
});
console.log(ans);
It seems I'm stuck with a simple regex for a password check.
What I'd like:
8 up to 30 symbols (Total)
With any of these: [A-Za-z\d]
And 0 up to 3 of these: [ -/:-#[-`{-~À-ÿ] (Special list)
I took a look here and then I wrote something like:
(?=.{8,15}$)(?=.*[A-Za-z\d])(?!([ -\/:-#[-`{-~À-ÿ])\1{4}).*
But it doesn't work, one can put more than 3 of the special chars list.
Any tips?
After shuffling your regex around a bit, it works for the examples you provided (I think you made a mistake with the example "A#~` C:", it should not match as it has 6 special chars):
(?!.*(?:[ -\/:-#[-`{-~À-ÿ].*){4})^[A-Za-z\d -\/:-#[-`{-~À-ÿ]{8,30}$
It only needs one lookahead instead of two, because the length and character set check can be done without lookahead: ^[A-Za-z\d -/:-#[-`{-~À-ÿ]{8,30}$
I changed the negative lookahead a bit to be correct. Your mistake was to only check for consecutive special chars, and you inserted the wildcards .* in a way that made the lookahead never hit (because the wildcard allowed everything).
Will this work?
string characters = " -/:-#[-`{-~À-ÿ";
string letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
string[] inputs = {
"AABBCCDD",
"aaaaaaaa",
"11111111",
"a1a1a1a1",
"AA####AA",
"A1C EKFE",
"AADE F"
};
foreach (string input in inputs)
{
var counts = input.Cast<char>().Select(x => new { ch = characters.Contains(x.ToString()) ? 1 : 0, letter = letters.Contains(x.ToString()) ? 1 : 0, notmatch = (characters + letters).Contains(x) ? 0 : 1}).ToArray();
Boolean isMatch = (input.Length >= 8) && (input.Length <= 30) && (counts.Sum(x => x.notmatch) == 0) && (counts.Sum(x => x.ch) <= 3);
Console.WriteLine("Input : '{0}', Matches : '{1}'", input, isMatch ? "Match" : "No Match");
}
Console.ReadLine();
I would use: (if you want to stick to Regex)
var specialChars = #" -\/:-#[-`{-~À-ÿ";
var regularChars = #"A-Za-z\d";
if (Regex.Match(password,$"^(.[{regularChars}{specialChars}]{7,29})$").Success && Regex.Matches(password, $"[{specialChars}]").Count<=3))
{
//Password OK
}
If consists of:
Check Length and if password contains illegal characters
Check if ony contains 3 times special char
A litle faster:
var specialChars = #" -\/:-#[-`{-~À-ÿ";
var regularChars = #"A-Za-z\d";
var minChars = 8;
var maxChars = 30;
if (password.Length >= minChars && password.Length <= maxChars && Regex.Match(password,$"^[{regularChars}{specialChars}]+$").Success && Regex.Matches(password, $"[{specialChars}]").Count<=3))
{
//Password OK
}
Newbie here..I think I've managed to get what you need but one of the test cases you shared was kinda weird..
A#~` C:
OK -- Match (3 specials, it's okay)
Shouldn't this be failed because it has more than 3 specials?
Could you perhaps try this? If it works I'll type out the explanations for the regex.
https://regex101.com/r/KCL6R1/2
(?=^[A-Za-z\d -\/:-#[-`{-~À-ÿ]{8,30}$)^(?:[A-Za-z\d]*[ -\/:-#[-`{-~À-ÿ]){0,3}[A-Za-z\d]*$
I've created a string value using padStart method (padLeft), for example:
"5".padStart(19, "0")
which results into "0000000000000000005"
How can I get that 5 back using regex?
I've tested this:
/^0*(\d+)$/.exec(d)[1]
which return 5 correctly.
But this regex returns null for something like "00000012.22"
Samples:
5 > 5
005 > 5
0011.22 > 11.22 >> This is a first problem!
00100 >> 100
001001 >> 1001
00.5 >> 0.5 This is a second problem!
Working codes but without regex:
function toDb(d) {
if (d == null) return null;
var precisionIndex = d.indexOf('.');
return d.toString().padStart((29 + precisionIndex + 1), '0');
}
function fromDb(d) {
if (d == null) return null;
d = d.replace(/^0+/, ''); // I'd like to use regex here
if (d.indexOf('.') == 0) // I'd like to use regex here
d = '0' + d; // I'd like to use regex here
return d;
}
fromDb(toDb('0.5')) returns 0.5 for me. But I'd like to use regex in my codes.
Use String#replace method to replace leading 0.
console.log(
"0000000000000000005".replace(/^0+(?=\d)/, '')
)
console.log(
"000000000000000000.5".replace(/^0+(?=\d)/, '')
)
In the regex start anchor(^) assert the beginning position of the string and 0+ matches combination one or more repetition of 0, altogether ^0+ matches 0s at the beginning.
UPDATE : To avoid removing 0 just before the . use positive look ahead assertion, (?=\d) match up to the 0 which follows a digit.
Hello my fellow dream builders.
I am parsing time from twitter and I am using this regex:
{
match = /^[1]/.exec(obj.tweetTime);
if(match != null){
time = "1 hour ago";
}
else
{
match = /^[0-9]{1,2}/.exec(obj.tweetTime);
time = match + " hours ago";
}
}
My question is, if there is simpler way to do this? As you can see, I have 2 digits for time. I just want to format my print right. Hour/Hours as you can see.
Is it possible to write only 1 regex and use only 1 conditional bracket?
PS: I am beginner at regex, and I know /^[0-9]{1,2}/ allow numbers from 0 to 99 practically, but as I said it works for my needs, just asking if it is possible to do this properly, since I lack knowledge.
Thank you, much love <3
I would do it like this:
var match = obj.tweetTime.match(/^\d+$/);
if (match) {
var time = match[0] + ' hour' + (match[0] == 1 ? '' : 's') + ' ago';
}
EDIT Turns out the string is formatted! In which case:
var match = obj.tweetTime.match(/^(\d+)([smhd])$/);
if (match) {
var units = { s: 'second', m: 'minute', h: 'hour', d: 'day' },
time = match[1] + ' ' + units[match[2]] + (match[1] == 1 ? '' : 's') + ' ago';
}
To explain the regex:
^ Anchor matches to the beginning of the string
(\d+) Capture one or more digits in first group
([smhd]) Capture s, m, h or d in second group
$ Anchor to end of string
I need a regular expression to validate a string with the following conditions
String might contain any of digits space + - () / .
If string contain anything else then it should be invalid
If there is any + in the string then it should be at the beginning and there should at most one + , otherwise it would be invalid, if there are more than one + then it is invalid
String should be 7 to 20 character long
It is not compulsory to have all these digits space + - () / .
But it is compulsory to contain at least 7 digit
I think you are validating phone numbers with E.164 format. Phone number can contain many other format. It can contain . too. Multiple spaces in a number is not uncommon. So its better to format all the numbers to a common format and store that format in db. If that common format is wrong you can throw error.
I validate those phone numbers like this.
function validate_phone($phone){
// replace anything non-digit and add + at beginning
$e164 = "+". preg_replace('/\D+/', '', $phone);
// check validity by length;
return (strlen($e164)>6 && strlen($e164)<21);
}
Here I store $e164 in Db if its valid.
Even after that you can not validate a phone number. A valid phone number format does not mean its a valid number. For this an sms or call is generated against the number and activation code is sent. Once the user inputs the code phone number is fully validated.
You can do this in one regex:
/^(?=(?:.*\d){7})[0-9 ()\/+-][0-9 ()\/-]{6,19}$/
However I would personally do something like:
/^[0-9 ()\/+-][0-9 ()\/-]{6,19}$/
And then strip any non-digit and see if the remaining string is 7 or longer.
Let's try ...
preg_match('/^(?=(?:.*\d){7})[+\d\s()\/\-\.][\d\s()\/\-\.]{6,19}$/', $text);
Breaking this down:
We start with a positive look-ahead that requires a digit at least 7 times.
Then we match all the valid characters, including the plus.
Followed by matching all the valid characters without plus between 6 and 20 times.
A little more concise:
^\+?(?=(.*\d){7})[()/\d-]{7,19}$
'Course, why would you even use regular expressions?
function is_valid($string) {
$digits = 0;
$length = strlen($string);
if($length < 7 || $length > 20) {
return false;
}
for($i = 0; $i < $length; $i++) {
if(ctype_digit($string[$i])) {
$digits++;
} elseif(strpos('+-() ', $string[$i]) === false && ($string[$i] !== '+' || $i !== 0)) {
return false;
}
}
return $digits >= 7;
}