Masking phone number with regex in javascript - javascript

My application has a specific phone number format which looks like 999.111.222, which I have a regex pattern to mask it on front-end:
/[0-9]{3}\.[0-9]{3}\.([0-9]{3})/
But recently, the format was changed to allow the middle three digits to have one less digit, so now both 999.11.222 and 999.111.222 match. How can I change my regex accordingly?
"999.111.222".replace(/[0-9]{3}\.[0-9]{3}\.([0-9]{3})/, '<div>xxx.xxx.$1</div>')
expected output:
"999.111.222" // xxx.xxx.222
"999.11.222" // xxx.xx.222

Replace {3} with {2,3} to match two or three digits.
/[0-9]{3}\.[0-9]{2,3}\.([0-9]{3})/
For reference see e.g. MDN

Use
console.log(
"999.11.222".replace(/[0-9]{3}\.([0-9]{2,3})\.([0-9]{3})/, function ($0, $1, $2)
{ return '<div>xxx.' + $1.replace(/\d/g, 'x') + '.' + $2 + '</div>'; })
)
The ([0-9]{2,3}) first capturing group will match 2 or 3 digits, and in the callback method used as the replacement argument, all the digits from th first group are replaced with x.
You may further customize the pattern for the first set of digits, too.

In fact, you should change not only your regex but also your callback replace function:
const regex = /[0-9]{3}\.([0-9]{2,3})\.([0-9]{3})/;
const cbFn = (all, g1, g2) =>`<div>xxx.xx${(g1.length === 3 ? 'x' : '')}.${g2}</div>`;
const a = "999.11.222".replace(regex, cbFn);
const b = "999.111.222".replace(regex, cbFn);
console.log(a, b);
To change regex you could add a term with {2,3} quantifier, as already suggested, and create a new group. Then, in replace cb function, you can use length to know if you must put a new x.

Related

Regular expression to isolate numbers from symbols and merge them as decimal numbers in JS

I am trying to isolate specific format groups within strings and convert them through JS or jQuery and regex, strings like these
#aba #abc #33-25
#02-20 #abe #abf
#abg #abe #00-50 #aba
#aja #255-45
to these
33.25€
2.20€
0.50€
255.45€
.
1. In regex level, my workaround so far for isolating #xx.xx groups within strings is
s = "#aba #abc #33-25"
s.match( /(#[W\d-]+)/ ) //["#33-25", "#33-25"]
It recognize the #33-25 substring but outputs it 2 times in an array which is obviously insufficient.
.
2. Also how it will work (JS or jQuery) to (solved by #Kosh's answer)
remove # symbols
replace hyphen symbol (-) to dot symbol (.)
when #01-xx or #0-xx to convert to 1.xx or 0.xx (where x is obviously decimal numbers, always 2)
Use match and replace:
const convert = (s) => s
.match(/#0*(0|[1-9]+)-(\d\d)\b/g)
.map(m => m.replace(/#0*(0|[1-9]+)-(\d\d)/g, '$1.$2€'));
console.log(convert(`#aba #abc #33-25
#02-20 #abe #abf
#abg #abe #00-50 #aba
#aja #255-45`))
You can use
const texts = ['#aba #abc #33-25','#02-20 #abe #abf','#abg #abe #00-50 #aba','#aja #255-45'];
texts.forEach( x => {
const m = x.match(/#(\d+)-(\d+)/);
if (m) {
console.log(x, '=>', `${m[1]}.${m[2]}€`);
}
});
Here, x.match(/#(\d+)-(\d+)/) finds the first match of a /#(\d+)-(\d+)/ regex (# matches a # char, (\d+) captures one or more digits into Group 1, - matches a hyphen and (\d+) captures one or more digits into Group 2) in a string, and then ${m[1]}.${m[2]}€ builds the final result where m[1] is Group 1 and m[2] is Group 2 value.

regex to extract numbers starting from second symbol

Sorry for one more to the tons of regexp questions but I can't find anything similar to my needs. I want to output the string which can contain number or letter 'A' as the first symbol and numbers only on other positions. Input is any string, for example:
---INPUT--- -OUTPUT-
A123asdf456 -> A123456
0qw#$56-398 -> 056398
B12376B6f90 -> 12376690
12A12345BCt -> 1212345
What I tried is replace(/[^A\d]/g, '') (I use JS), which almost does the job except the case when there's A in the middle of the string. I tried to use ^ anchor but then the pattern doesn't match other numbers in the string. Not sure what is easier - extract matching characters or remove unmatching.
I think you can do it like this using a negative lookahead and then replace with an empty string.
In an non capturing group (?:, use a negative lookahad (?! to assert that what follows is not the beginning of the string followed by ^A or a digit \d. If that is the case, match any character .
(?:(?!^A|\d).)+
var pattern = /(?:(?!^A|\d).)+/g;
var strings = [
"A123asdf456",
"0qw#$56-398",
"B12376B6f90",
"12A12345BCt"
];
for (var i = 0; i < strings.length; i++) {
console.log(strings[i] + " ==> " + strings[i].replace(pattern, ""));
}
You can match and capture desired and undesired characters within two different sides of an alternation, then replace those undesired with nothing:
^(A)|\D
JS code:
var inputStrings = [
"A-123asdf456",
"A123asdf456",
"0qw#$56-398",
"B12376B6f90",
"12A12345BCt"
];
console.log(
inputStrings.map(v => v.replace(/^(A)|\D/g, "$1"))
);
You can use the following regex : /(^A)?\d+/g
var arr = ['A123asdf456','0qw#$56-398','B12376B6f90','12A12345BCt', 'A-123asdf456'],
result = arr.map(s => s.match(/(^A|\d)/g).join(''));
console.log(result);

single regex to capitalize first letter and replace dot

Trying out with a regex for simple problem. My input string is
firstname.ab
And am trying to output it as,
Firstname AB
So the main aim is to capitalize the first letter of the string and replace the dot with space. So chose to write two regex to solve.
First One : To replace dot with space /\./g
Second One : To capitalize the first letter /\b\w/g
And my question is, Can we do both operation with a single regex ?
Thanks in advance !!
You can use a callback function inside the replace:
var str = 'firstname.ab';
var result = str.replace(/^([a-zA-Z])(.*)\.([^.]+)$/, function (match, grp1, grp2, grp3, offset, s) {
return grp1.toUpperCase() + grp2 + " " + grp3.toUpperCase();
});
alert(result);
The grp1, grp2 and grp3 represent the capturing groups in the callback function. grp1 is a leading letter ([a-zA-Z]). Then we capturing any number of character other than newline ((.*) - if you have linebreaks, use [\s\S]*). And then comes the literal dot \. that we do not capture since we want to replace it with a space. And lastly, the ([^.]+$) regex will match and the capture all the remaining substring containing 1 or more characters other then a literal dot till the end.
We can use capturing groups to re-build the input string this way.
var $input = $('#input'),
value = $input.val(),
value = value.split( '.' );
value[0] = value[0].charAt( 0 ).toUpperCase() + value[0].substr(1),
value[1] = value[1].toUpperCase(),
value = value.join( ' ' );
$input.val( value );
It would be much easier if you simply split the value, process the string in the array, and join them back.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" value="first.ab" id="input">

javascript regexp, select from certain type of url

I'm making a url filter using javascript
i get a parameter from url
parameter 1 = /name/123
//description /text/number
parameter 2 = /name/name/121
//description /text/text/number
var filter = /[/a-z][/][0-9]/;
if(filter.test(page) == true){
//do code;
}
I made it to select a parameter 1, however it selects parameter 2 too.
what should I fix to select the only parameter 1 or parameter 2 separately?
Thank you.
Try this:
var filter = /^\/[^/]+\/\d+$/;
// or
var filter = /^\/[a-z]+\/\d+$/i;
That is to say that you can match on:
^ beginning of string
\/ a / (escaped for the regex literal)
[^/]+ one or more non-slash characters in a row, or
[a-z]+ one or more letters in a row
\/ another slash
\d+ one or more digits
$ end of string
Note also that your if test doesn't need the ==true part, you can just say:
if(filter.test(page)){
The pattern you use is invalid, it matches only one character followed by / followed by one digit.
Try using this pattern:
PATTERN
/^\/[a-z]+?\/\d+$/
INPUT
1. /name/name/121
2. /name/123
OUTPUT
1. false
2. true
I've slightly modified nnnnnn's version by the addition of a quantifier : (this pattern){n times} which gives /^(\/[^/]+){n}\/\d+$/. See nnnnnn's answer for more details.
function createRegex(n) {
return new RegExp(
'^(\\/[^/]+){' + n + '}\\/\\d+$'
);
}
var twoParts = createRegex(2);
twoParts.test('/part1/part2/123'); // true
twoParts.test('/part1/part2/part3/123'); // false
To split the url into multiple parts :
var parts = '/part1/part2/123'.match(/[^/]+/g);
var part1 = parts[0]; // "part1"
var part2 = parts[1]; // "part2"
var part3 = parts[2]; // "123"
Be careful though, match returns null in case of failure.

Regex using javascript to return just numbers

If I have a string like "something12" or "something102", how would I use a regex in javascript to return just the number parts?
Regular expressions:
var numberPattern = /\d+/g;
'something102asdfkj1948948'.match( numberPattern )
This would return an Array with two elements inside, '102' and '1948948'. Operate as you wish. If it doesn't match any it will return null.
To concatenate them:
'something102asdfkj1948948'.match( numberPattern ).join('')
Assuming you're not dealing with complex decimals, this should suffice I suppose.
You could also strip all the non-digit characters (\D or [^0-9]):
let word_With_Numbers = 'abc123c def4567hij89'
let word_Without_Numbers = word_With_Numbers.replace(/\D/g, '');
console.log(word_Without_Numbers)
For number with decimal fraction and minus sign, I use this snippet:
const NUMERIC_REGEXP = /[-]{0,1}[\d]*[.]{0,1}[\d]+/g;
const numbers = '2.2px 3.1px 4px -7.6px obj.key'.match(NUMERIC_REGEXP)
console.log(numbers); // ["2.2", "3.1", "4", "-7.6"]
Update: - 7/9/2018
Found a tool which allows you to edit regular expression visually: JavaScript Regular Expression Parser & Visualizer.
Update:
Here's another one with which you can even debugger regexp: Online regex tester and debugger.
Update:
Another one: RegExr.
Update:
Regexper and Regex Pal.
If you want only digits:
var value = '675-805-714';
var numberPattern = /\d+/g;
value = value.match( numberPattern ).join([]);
alert(value);
//Show: 675805714
Now you get the digits joined
I guess you want to get number(s) from the string. In which case, you can use the following:
// Returns an array of numbers located in the string
function get_numbers(input) {
return input.match(/[0-9]+/g);
}
var first_test = get_numbers('something102');
var second_test = get_numbers('something102or12');
var third_test = get_numbers('no numbers here!');
alert(first_test); // [102]
alert(second_test); // [102,12]
alert(third_test); // null
IMO the #3 answer at this time by Chen Dachao is the right way to go if you want to capture any kind of number, but the regular expression can be shortened from:
/[-]{0,1}[\d]*[\.]{0,1}[\d]+/g
to:
/-?\d*\.?\d+/g
For example, this code:
"lin-grad.ient(217deg,rgba(255, 0, 0, -0.8), rgba(-255,0,0,0) 70.71%)".match(/-?\d*\.?\d+/g)
generates this array:
["217","255","0","0","-0.8","-255","0","0","0","70.71"]
I've butchered an MDN linear gradient example so that it fully tests the regexp and doesn't need to scroll here. I think I've included all the possibilities in terms of negative numbers, decimals, unit suffixes like deg and %, inconsistent comma and space usage, and the extra dot/period and hyphen/dash characters within the text "lin-grad.ient". Please let me know if I'm missing something. The only thing I can see that it does not handle is a badly formed decimal number like "0..8".
If you really want an array of numbers, you can convert the entire array in the same line of code:
array = whatever.match(/-?\d*\.?\d+/g).map(Number);
My particular code, which is parsing CSS functions, doesn't need to worry about the non-numeric use of the dot/period character, so the regular expression can be even simpler:
/-?[\d\.]+/g
var result = input.match(/\d+/g).join([])
Using split and regex :
var str = "fooBar0123".split(/(\d+)/);
console.log(str[0]); // fooBar
console.log(str[1]); // 0123
The answers given don't actually match your question, which implied a trailing number. Also, remember that you're getting a string back; if you actually need a number, cast the result:
item=item.replace('^.*\D(\d*)$', '$1');
if (!/^\d+$/.test(item)) throw 'parse error: number not found';
item=Number(item);
If you're dealing with numeric item ids on a web page, your code could also usefully accept an Element, extracting the number from its id (or its first parent with an id); if you've an Event handy, you can likely get the Element from that, too.
As per #Syntle's answer, if you have only non numeric characters you'll get an Uncaught TypeError: Cannot read property 'join' of null.
This will prevent errors if no matches are found and return an empty string:
('something'.match( /\d+/g )||[]).join('')
Here is the solution to convert the string to valid plain or decimal numbers using Regex:
//something123.777.321something to 123.777321
const str = 'something123.777.321something';
let initialValue = str.replace(/[^0-9.]+/, '');
//initialValue = '123.777.321';
//characterCount just count the characters in a given string
if (characterCount(intitialValue, '.') > 1) {
const splitedValue = intitialValue.split('.');
//splittedValue = ['123','777','321'];
intitialValue = splitedValue.shift() + '.' + splitedValue.join('');
//result i.e. initialValue = '123.777321'
}
If you want dot/comma separated numbers also, then:
\d*\.?\d*
or
[0-9]*\.?[0-9]*
You can use https://regex101.com/ to test your regexes.
Everything that other solutions have, but with a little validation
// value = '675-805-714'
const validateNumberInput = (value) => {
let numberPattern = /\d+/g
let numbers = value.match(numberPattern)
if (numbers === null) {
return 0
}
return parseInt(numbers.join([]))
}
// 675805714
One liner
I you do not care about decimal numbers and only need the digits, I think this one liner is rather elegant:
/**
* #param {String} str
* #returns {String} - All digits from the given `str`
*/
const getDigitsInString = (str) => str.replace(/[^\d]*/g, '');
console.log([
'?,!_:/42\`"^',
'A 0 B 1 C 2 D 3 E',
' 4 twenty 20 ',
'1413/12/11',
'16:20:42:01'
].map((str) => getDigitsInString(str)));
Simple explanation:
\d matches any digit from 0 to 9
[^n] matches anything that is not n
* matches 0 times or more the predecessor
( It is an attempt to match a whole block of non-digits all at once )
g at the end, indicates that the regex is global to the entire string and that we will not stop at the first occurrence but match every occurrence within it
Together those rules match anything but digits, which we replace by an empty strings. Thus, resulting in a string containing digits only.

Categories

Resources