Match exactly 10 digits with unknown boundaries? - javascript

Is there any regex I can use to match blocks of exactly 10 digits? For instance, I have this:
/\d{10}(?!\d+)/g
And this matches 2154358383 when given 2154358383 fine, but is also matches 1213141516 when given 12345678910111213141516, which I don't want.
What I think I need is a look-behind assertion (in addition to my lookahead already in there), that checks to make sure the character preceding the match is not an integer, but I can't figure out how to do that.
I tried
/(?:[^\d]+)\d{10}(?!\d+)/g
But that broke my first match of 2154358383, which is bad.
How can I write this to only match groups of 10 integers (no more, no less) with unknown boundaries?
I should also note that I'm trying to extract these out of a much larger string, so ^ and $ are out of the question.

This should work: ([^\d]|^)\d{10}([^\d]|$)

Could you do something like:
([^\d]|^)(\d{10})([^\d]|$)
In other words, the beginning of the string or a non-digit, ten digits, then the end of the string or a non-digit. That should solve the cases you looked for above.
You can use the regex like this:
var regex = /([^\d]|^)(\d{10})([^\d]|$)/;
var match = regex.exec(s);
var digits = match[2];

This should match numbers at the beginning of the string (the ^) or in the middle/end (the [^\d] and the (?!\d). If you care about the exact match and not just that it matches in the first place, you'll need to grab the first group in the match.
/(?:[^\d]|^)(\d{10})(?!\d)/g
This would be easier if JavaScript regular expressions supported lookbehind.

What about the next?
perl -nle 'print if /(\b|\D)(\d{10})(\D|\b)/' <<EOF
123456789
x123456789
123456789x
1234567890
x1234567890
1234567890x
12345678901
x12345678901
x12345678901x
EOF
will print only
1234567890
x1234567890
1234567890x

I know you said "no ^" but maybe it's okay if you use it like this?:
rx = /(?:^|\D)(\d{10})(?!\d)/g
Here's a quick test:
> val = '1234567890 sdkjsdkjfsl 2234567890 323456789000 4234567890'
'1234567890 sdkjsdkjfsl 2234567890 323456789000 4234567890'
> rx.exec(val)[1]
'1234567890'
> rx.exec(val)[1]
'2234567890'
> rx.exec(val)[1]
'4234567890'

Try this
var re = /(?:^|[^\d])(\d{10})(?:$|[^\d])/g
re.exec ( "2154358383")
//["2154358383", "2154358383"]
re.exec ( "12345678910111213141516" )
//null
re.exec ( "abc1234567890def" )
//["c1234567890d", "1234567890"]
val = '1234567890 sdkjsdkjfsl 2234567890 323456789000 4234567890';
re.exec ( val )
//["1234567890 ", "1234567890"]
re.exec ( val )
//[" 2234567890 ", "2234567890"]
re.exec ( val )
//[" 4234567890", "4234567890"]
re.exec ( val )
//null

Simple with lookbehind:
/(?<!\d)\d{10}(?!\d)/g

i would cheat and do something like
if (myvar.toString().substring(1, 10) = "1234567890") ....
:)

Related

JS Regex for a string contains fixed number of letters

Let's say I need to have minimum 5 letters in a string not requiring that they are subsequent. The regex below checks subsequent letters
[A-Za-z]{5,}
So, "aaaaa" -- true, but "aaa1aa" -- false.
What is the regex to leave the sequence condition, that both of the strings above would pass as true.
You could remove all non-letter chars with .replace(/[^A-Za-z]+/g, '') and then run the regex:
var strs = ["aaaaa", "aaa1aa"];
var val_rx = /[a-zA-Z]{5,}/;
for (var s of strs) {
console.log( val_rx.test(s.replace(/[^A-Za-z]+/g, '')) );
}
Else, you may also use a one step solution like
var strs = ["aaaaa", "aaa1aa"];
var val_rx = /(?:[^a-zA-Z]*[a-zA-Z]){5,}/;
for (var s of strs) {
console.log( s, "=>", val_rx.test(s) );
}
See this second regex demo online. (?:[^a-zA-Z]*[a-zA-Z]){5,} matches 5 or more consecutive occurrences of 0 or more non-letter chars ([^a-zA-Z]*) followed with a letter char.
Allow non-letter characters between the letters:
(?:[A-Za-z][^A-Za-z]*){5,}
If you have to use a regular expression only, here's one somewhat ugly option:
const check = str => /^(.*[A-Za-z].*){5}/.test(str);
console.log(check("aaaaa"));
console.log(check("aa1aaa"));
console.log(check("aa1aa"));
w means alphanumeric in regex,
it will be ok : \w{5,}
[a-zA-Z0-9]{5,}
Just like this? Or do you mean it needs to be a regex that ignores digits? Because the above would match aaaa1 as well.

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);

Extract word between '=' and '('

I have the following string
234234=AWORDHERE('sdf.'aa')
where I need to extract AWORDHERE.
Sometimes there can be space in between.
234234= AWORDHERE('sdf.'aa')
Can I do this with a regular expression?
Or should I do it manually by finding indexes?
The datasets are huge, so it's important to do it as fast as possible.
Try this regex:
\d+=\s?(\w+)\(
Check Demo
in Javascript it would like that:
var myString = "234234=AWORDHERE('sdf.'aa')";// or 234234= AWORDHERE('sdf.'aa')
var myRegexp = /\d+=\s?(\w+)\(/g;
var match = myRegexp.exec(myString);
console.log(match[1]); // AWORDHERE
You could do this at least three ways. You need to benchmark to see what's fastest.
Substring w/ indexes
function extract(from) {
var ixEq = from.indexOf("=");
var ixParen = from.indexOf("(");
return from.substring(ixEq + 1, ixParen);
}
.
Splits
function extract(from) {
var spEq = from.split("=");
var spParen = spEq[1].split("(");
return spParen[0];
}
Regex (demo)
Here is some sample regex you could use
/[^=]+=([^(]+).*/g
This says
[^=]+ - One or more character which is not an =
= - The = itself
( - creates a matching group so you can access your match in code
[^(]+ - One or more character which is not a (
) - closes the matching group
.* - Matches the rest of the line
the /g on the end tells it to perform the match on all lines.
Using look around you can search for string preceded by = and followed by ( as following.
Regex: (?<==)[A-Z ]+(?=\()
Explanation:
(?<==) checks if [A-Z ] is preceded by an =.
[A-Z ]+ matches your pattern.
(?=\() checks if matched pattern is followed by a (.
Regex101 Demo
var str = "234234= AWORDHERE('sdf.'aa')";
var regexp = /.*=\s+(\w+)\(.*\)/g;
var match = regexp.exec(str);
alert( match[1] );
I made my solution for this just a little more general than you asked for, but I don't think it takes much more time to execute. I didn't measure. If you need greater efficiency than this provides, comment and I or someone else can help you with that.
Here's what I did, using the command prompt of node:
> var s = "234234= AWORDHERE('sdf.'aa')"
undefined
> var a = s.match(/(\w+)=\s*(\w+)\s*\(.*/)
undefined
> a
[ '234234= AWORDHERE(\'sdf.\'aa\')',
'234234',
'AWORDHERE',
index: 0,
input: '234234= AWORDHERE(\'sdf.\'aa\')' ]
>
As you can see, this matches the number before the = in a[1], and it matches the AWORDHERE name as you requested in a[2]. This will work with any number (including zero) spaces before and/or after the =.

javascript regular expression test for 6 digit numbers only. comma seperated

and so this must pass:
454555, 939999 , 019999 ,727663
its for a user entering 6 digit invoice numbers. it should fail if a number is 5 or 7 digit and not 6. so 1234567, 123456 should fail, as one set is more than 6 numbers.
So far I have :
[0-9]{6}(\s*,*,\s*[0-9]{6})*
which only draw back is that it accepts 7 or more digit numbers. cant figure out if its even possible at this point to do both, test for 6 digits separated by a comma and one or more space, and all the digits have to be only 6 digits and fail if one is not.
any help appreciated. regular expressions are not my forte.
thanks
Norman
You can write it using regex like the function below.
const isPassword = (password: string) => /^\d{6}$/gm.test(password);
And here is an example test file below.
test('should recognize a valid password', () => {
expect(isPassword('123456')).toBe(true);
expect(isPassword('000000')).toBe(true);
});
test('should recognize an invalid password', () => {
expect(isPassword('asdasda1234')).toBe(false);
expect(isPassword('1234567')).toBe(false);
expect(isPassword('a123456a')).toBe(false);
expect(isPassword('11.11.11')).toBe(false);
expect(isPassword('aaaaaa')).toBe(false);
expect(isPassword('eeeeee')).toBe(false);
expect(isPassword('......')).toBe(false);
expect(isPassword('werwerwerwr')).toBe(false);
});
In order to validate the full string you can use this regex.
^(\s*\d{6}\s*)(,\s*\d{6}\s*)*,?\s*$
It works with six digits only, and you have to enter at least one 6 digit number.
It also works if you have a trailing comma with whitespaces.
It's accepting more than six digit numbers because you're not anchoring the text, and for some odd reason you're optionally repeating the comma. Try something like this:
^[0-9]{6}(?:\s*,\s*[0-9]{6})*$
Also note that [0-9] is equivalent to \d, so this can be rewritten more concisely as:
^\d{6}(?:\s*,\s*\d{6})*$
Your regex does not match 7 digits in a row, but it also doesn't enforce that it matches the whole string. It just has to match some substring in the string, so it would also match each of these:
"1234512345612345612345"
"NaNaNaN 123456, 123456 BOOO!"
"!##$%^&*({123456})*&^%$##!"
Just add the start of string (^) and end of string ($) anchors to enforce that the whole string matches and it will work correctly:
^[0-9]{6}(\s*,*,\s*[0-9]{6})*$
Also note that ,*, could be shortened to ,+, and if you only want one comma in a row, just use ,, not ,* or ,+.
You can also replace [0-9] with \d:
^\d{6}(\s*,\s*\d{6})*$
Using only regex:
var commaSeparatedSixDigits = /^(?:\d{6}\s*,\s*)*\d{6}$/;
if (myInput.test(commaSeparatedSixDigits)) console.log( "Is good!" );
This says:
^ - Starting at the beginning of the string
(?:…)* - Find zero or more of the following:
\d{6} - six digits
\s* - maybe some whitespace
, - a literal comma
\s* - maybe some whitespace
\d{6} - Followed by six digits
$ - Followed by the end of the string
Alternatively:
var commaSeparatedSixDigits = /^\s*\d{6}(?:\s*,\s*\d{6})*\s*$/;
I leave it as an exercise to you to decipher what's different about this.
Using JavaScript + regex:
function isOnlyCommaSeparatedSixDigitNumbers( str ){
var parts = srt.split(/\s*,\s*/);
for (var i=parts.length;i--;){
// Ensure that each part is exactly six digit characters
if (! /^\d{6}$/.test(parts[i])) return false;
}
return true;
}
I see a lot of complication here. Sounds to me like what you want is pretty simple:
/^(\d{6},)*\d{6}$/
Then we account for whitespace:
/^\s*(\d{6}\s*,\s*)*\d{6}\s*$/
But as others have noted, this is actually quite simple in JavaScript without using regex:
function check(input) {
var parts = input.split(',');
for (var i = 0, n = parts.length; i < n; i++) {
if (isNaN(+parts[i].trim())) {
return false;
}
}
return true;
}
Tested in the Chrome JavaScript console.
There isn;t any real need for a regexp. Limit the input to only 6 characters, only accept numbers and ensure that the input has 6 digits (not show here). So you would need:
HTML
<input type='text' name='invoice' size='10' maxlength='6' value='' onkeypress='evNumersOnly(event);'>
JavaScript
<script>
function evNumbersOnly( evt ) {
//--- only accepts numbers
//--- this handles incompatabilities between browsers
var theEvent = evt || window.event;
//--- this handles incompatabilities between browsers
var key = theEvent.keyCode || theEvent.which;
//--- convert key number to a letter
key = String.fromCharCode( key );
var regex = /[0-9]/; // Allowable characters 0-9.+-,
if( !regex.test(key) ) {
theEvent.returnValue = false;
//--- this prevents the character from being displayed
if(theEvent.preventDefault) theEvent.preventDefault();
}
}
</script>

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