i have the following string
foo: 21, bar: 11
where foo and bar are not constants, so I'm trying to match all the digits after the last ":"(colon) character.
const myString = 'foo: 21, bar: 11'
myString.match(/\d+/g).shift().join() -> 11
can i do the same just with pure regex?
thanks!
Using negative regex you can use this regex:
/\d+(?![^:]*:)/g
RegEx Demo
(?![^:]*:) is negative lookahead to assert that there is no : ahead of digits we are matching.
Code Demo:
var myString = 'foo: 21, bar: 11';
console.log(myString.match(/\d+(?![^:]*:)/g));
var myString = 'foo: 21, bar: 11';
console.log(myString.replace(/(.)*\:\s?/,''));
You may use either of the two solutions:
This one will match up to the last : and grab the digits after 0+ whitespaces:
var s = "foo: 21, bar: 11";
var m = s.match(/.*:\s*(\d+)/);
if (m !== null) {
console.log(m[1]);
}
And this one will find a : followed with 0+ whitespaces, then will capture 1+ digits into Group 1 and then will match 0+ chars other than : up to the end of string.
var s = "foo: 21, bar: 11";
m1 = s.match(/:\s*(\d+)[^:]*$/);
if (m1 !== null) {
console.log(m1[1]);
}
Related
i want to create a regex to "- any number + unit" in a string
for example i have this string:
hello- world- 86 lo. => 86 lo
in the -world- 6 lb => 6 lb
and- the- dog -8kl => 8kl
let data='in the world- 6 lo'
let reg = /-[0-9][a-z]/gi;
let matches = data.match(reg);
console.log(matches)
with his answer:
let data='in the world- 6 lo'
let reg = /-\s*([0-9]+\s*[a-z]+)/;
let matches = data.match(reg);
console.log(matches)
i get two answer
[
"- 6 lo",
"6 lo"
]
i want to get only the second => "6 lo"
Match the hyphen and 0+ whitespace chars. The capture in group 1 matching 1+ digits, optional whitespace chars and 1 or more chars a-z.
A specific match with an optional decimal part, adding the units:
-\s*([0-9]+(?:\.\d+)?(?:\s*(?:l[ob]|kl))?)\b
Regex demo
const regex = /-\s*([0-9]+(?:\.\d+)?(?:\s*(?:l[ob]|kl))?)\b/g;
const str = `hello- world- 86 lo
in the -world- 6 lb
and- the- dog -8kl
hello- world- 86.6 lo
hello- world- 86`;
while ((m = regex.exec(str)) !== null) {
console.log(m[1]);
}
Or a more broad match:
-\s*([0-9]+(?:\.\d+)?(?:\s*[a-z]+)?)\b
Regex demo
const regex = /-\s*([0-9]+(?:\.\d+)?(?:\s*[a-z]+)?)\b/g;
const str = `hello- world- 86 lo
in the -world- 6 lb
and- the- dog -8kl
hello- world- 86.6 lo
hello- world- 86`;
let m;
while ((m = regex.exec(str)) !== null) {
console.log(m[1]);
}
let data='in the world- 6 lo'
let reg = /\d+\s?[A-Za-z]{2}/gi;
let matches = data.match(reg);
console.log(matches)
try this, you can replace [A-Za-z] with the only units you need.
Well your data is a little odd, especially in the last case where it seems like the value might be negative. However, this regex should work for the cases you describe, and you can recombine the parts (sign, value, and unit) in whatever way you want afterward.
let data1 = 'in the world- 6 lo'
let data2 = 'in the -world- 6 lb'
let data3 = 'and- the- dog -8kl'
let reg = /- ?(-|\+)?(\d+\.?\d*) ?(\w+)/;
[data1, data2, data3].forEach(s => {
console.log("Checking string:", s);
const matches = s.match(reg);
console.log("Sign:", matches[1] ?? "+");
console.log("Value:", matches[2]);
console.log("Unit:", matches[3]);
});
Note that I'd avoid using the global flag g since it prevents the .match method from returning the contents of each capture group.
Make a match against the regexp and then map the result-array of this to get rid of the "- " at the beginning and return it.
In the regexp the minus had to be masked with , the spaces are optional, the unit accept all letters. If there are e.g. only max 2 letters wished than add {1,2}.
Because you wanted all results in the string (the g-parameter) I can't use the brackets in the regexp. So I had to map over the results and use here another regexp to get the desired part of the results.
function test(str) {
let reg = /\- ?[0-9]+ ?[a-z]+/gi;
let result = str.match(reg);
return result.map(res => {
return res.match(/\- ?(.*)/)[1];
});
}
console.log(test('hello- world- 86 lo, test-912 kg.'));
console.log(test('in the -world- 6 lb '));
console.log(test('and- the- dog -8kl'));
Hello I have a plate number BZ8345LK and want convert to BZ 8345 LK (adding space between char and number).
I tried with this Regex but not working, only space first char with number. Ex BZ 8345LK, the 'LK' keep not space with number.
var str = 'BZ8345LK';
str.replace(/[^0-9](?=[0-9])/g, '$& ');
# return BZ 8345LK, I want BZ 8345 LK
You can use this regex
[a-z](?=\d)|\d(?=[a-z])
[a-z](?=\d) - Match any alphabet followed by digit
| - Alternation same as logical OR
\d(?=[a-z]) - Any digit followed by alphabet
let str = 'BZ8345LK'
let op = str.replace(/[a-z](?=\d)|\d(?=[a-z])/gi, '$& ')
console.log(op)
You should alternate with the other possibility, that a number is followed by a non-number:
var str = 'BZ8345LK';
console.log(str.replace(/[^0-9](?=[0-9])|[0-9](?=[^0-9])/g, '$& '));
An anoher option is to use:
^[^\d]+|[\d]{4}
Search for any not numeric character [^\d] followed by 4 numeric [\d]{4} characters
const str = 'BZ8345LK'
let answer = str.replace(/^[^\d]+|[\d]{4}/gi, '$& ')
console.log(answer)
Try with this
var str = "BZ8345LK";
var result = str.replace(/([A-Z]+)(\d+)([A-Z]+)/, "$1 $2 $3");
console.log(result);
I have a string something like and I want to match just the first '{' of every {{xxxx}} pattern
{{abcd}}{{efg}}{{hij}}
{{abcd}}{{efg}}{{hij}}{
I tried with /(\s|^|.){/g but this pattern matches
{{abcd}}{{efg}}{{hij}}
Can some one guide me in the right direction
You need to use /(^|[^{]){/g (that matches and captures into Group 1 start-of-string or any char other than {, and then matches a {) and check if Group 1 matched at each RegExp#exec iteration. Then, if Group 1 matched, increment the match index:
var re = /(^|[^{]){/g;
var str = "{{abcd}}{{efg}}{{hij}}\n{{abcd}}{{efg}}{{hij}}{";
// 0 8 15 23 31 38 45
var m, indices = [];
while ((m = re.exec(str)) !== null) {
indices.push(m.index + (m[1] ? 1 : 0));
}
console.log(indices);
I need a regex which will test the combination of hexadecimal string. Specifically, the string must have:
Atleast one digit in the range 0 - 9,
At least one digit in the range A - F,
be 12 characters long.
String should not start with 0
Currently I am using var macRegex = new RegExp("^[0-9A-Fa-f]{12}$");. The above regex allow strings like "111111111111" , "000000000000" which i want to avoid . It should allow a string like "944a0c122123"
How can I accomplish this?
To keep the regular expression simple, I'd separate matching the pattern and checking the length:
var re = /^(\d+[a-f]+[\da-f]*|[a-f]+\d+[\da-f]*)$/i;
var s = '011001aFFA77';
console.log(re.test(s) && s.length == 12); // true
var s = '000000000000';
console.log(re.test(s) && s.length == 12); // false
The pattern to match:
one or more digits followed by one or more letters a to f followed by zero or more digits or letters a to f, OR
one or more letters a to f followed by one or more digits followed by zero or more digits or letters a to f
then check the length is 12.
Edit
To meet the new criterion "can't start with 0" (and simplify the expression a bit), the regular expression can be:
var re = /^([1-9]\d*[a-f]+|[a-f]+\d+)[\da-f]*$/i;
var s = '011001aFFA77';
console.log(re.test(s) && s.length == 12); // false
var s = '000000000000';
console.log(re.test(s) && s.length == 12); // false
var s = '011001aFFA77';
console.log(re.test(s) && s.length == 12); // false
var s = 'a11001aFFA77';
console.log(re.test(s) && s.length == 12); // true
var s = '311001aFFA77';
console.log(re.test(s) && s.length == 12); // true
var s = '0000000000a1';
console.log(re.test(s) && s.length == 12); // false
If you don't mind a non RegExp solution this function should do what you want.
function only_hex_len_12(str){
// if the string is the wrong length return false
if(str.length!=12) return false;
var hex_val=parseInt(str,16);
var dec_val=parseInt(str,10);
// If the string is dec return false
if(!isNaN(dec_val)) return false;
// If the string is not hex return false
if(isNaN(hex_val)) return false;
// Otherwise the string is okay so return true
return true;
}
If you want a RegExp solution RobG's answer looks good.
Here is the way I'd go:
/^(?=.*\d)(?=.*[a-f])[1-9a-f][\da-f]{10}[1-9a-f]$/i
Explanation:
/
^ : begining of string
(?=.*\d) : lookahead, at least one digit
(?=.*[a-f]) : lookahead, at least one letter in range a-f
[1-9a-f] : first character, not zero
[\da-f]{10} : ten hex character
[1-9a-f] : last character, not zero
$ : end of string
/i : case insensitive
You can use a set of positive lookaheads to do this.
Here's the regex:
/(?!0).(?=.*\d)(?=.*[a-f])[\da-f]{11}/i
(?!0) Negative lookahead
. Match any character
(?= Positive lookahead
.* Match any character zero to unlimited
\d Match a digit
)
(?= Positive lookahead
.* Match any character zero to unlimited
[a-f] Match a character a-f
)
[\da-f]{11} Match any of the valid characters, 12 times
You can conceptualize this is a logical AND of the expressions in each lookahead (except for the .*).
var regexp = /(?!0).(?=.*\d)(?=.*[a-f])[\da-f]{11}/i;
var test1 = "000000000000";
var test2 = "111111111111";
var test3 = "8179acf0871a";
var test4 = "9abzzzzzzzzz";
var test5 = "0179acf0871a";
console.log(regexp.test(test1));
console.log(regexp.test(test2));
console.log(regexp.test(test3));
console.log(regexp.test(test4));
console.log(regexp.test(test5));
Here's a snippet that demonstrates similar input samples.
i want to match a known number(floating point or integer) with a string and finding number of that repeat.
like match 22 in "22.5 98 12 22 322"
how i can do it with regular expression ?
try using this:
if (numbers.indexOf("22") != -1) {
//The number 22 is in the String
}
It's not exactly a regex but why use it when you don't need it?
str.match(/substr/g).length
returns number of occurrences of "substr" in "str". For example:
str = "22.5 98 12 22 322"
num = str.match(/22/g).length
alert(num) // 3
If you want to match integers rather than just substrings, make sure the number is preceded and followed by a space:
str = "22.5 98 12 22 322"
num = str.match(/(^|\s)22($|\s)/g).length
alert(num) // 1
Another option, without regular expressions:
str = "22.5 98 12 22 322"
num = str.split(" ").filter(function(item) {
return Number(item) === 22;
}).length;
If you mean you should find only the numbers that repeat within the same string, you can use something like this:
var test_str = '22 34 55 45345 34 22 555';
var matches = test_str.match(/(\b[0-9]+\b)(?=.+\b\1\b)/g);
// matches contains ["22", "34"], but not "55"
var str = "22.5 98 12 22 322";
var pattern = /22/g;
if (pattern.test(str)) {
// it matches "22", do your logic here...
}
see RegExp and RegExp.test(string) for more
Corrolating integer/floating point numbers from text to regex is
very tricky, since regex has no such concept.
With dynamic input, all the work is constructing the regex programatically.
This example doesn't include scientific notation, but it could.
Pseudo code:
If the input matches this parse regex
/^ (?=.*\d) // must be a digit in the input
([+-]?) // capt (1), optional +/-
[0]* // suck up all leading 0's
(\d*) // capt (2), optional digits, will start with [1-9]
([.]?) // capt (3), optional period
(\d*?) // capt (4), non-greedy optional digits, will start with [1-9]
[0]* // suck up all trailing 0's
$/x
sign = '[+]?';
If !length $2 AND !length $4
sign = '[+-]';
Else
If $1 == '-'
sign = '[-]';
Endif
Endif
whole = '[0]*';
If length $2
whole = '[0]*' + $2;
Endif
decfrac = '[.]? [0]*';
If length $4
$decfrac = '[.] ' + $4 + '[0]*';
Endif
regex = '/(?:^|\s)(?=\S*\d) ' + "$sign $whole $decfrac" + ' (?:\s|$)/x';
Else
// input is not valid
Endif
This is a Perl test case.
The dynamic regex produced has not been tested,
I asume it works but I could be wrong.
#samps = (
'00000.0',
'+.0',
'-.0',
'0.',
'-0.00100',
'1',
'+.1',
'+43.0910',
'22',
'33.e19',
);
for (#samps)
{
print "\nInput: $_\n";
if( /^ (?=.*\d) ([+-]?) [0]*(\d*) ([.]?) (\d*?)[0]*$/x ) # 1,2,3,4
{
my ($sign, $whole, $decfrac);
$sign = '[+]?';
if ( !length $2 && !length $4) {
$sign = '[+-]';
} elsif ($1 eq '-') {
$sign = '[-]';
}
$whole = '[0]*';
if ( length $2) {
$whole = '[0]*'.$2;
}
$decfrac = '[.]? [0]*';
if ( length $4) {
$decfrac = '[.] '.$4.'[0]*';
}
my $regex = '/(?:^|\s)(?=\S*\d) '. "$sign $whole $decfrac" . ' (?:\s|$)/x';
print "Regex: $regex\n";
}
else {
print "**input '$_' is not valid\n";
next;
}
}
Output
Input: 00000.0
Regex: /(?:^|\s)(?=\S*\d) [+-] [0]* [.]? [0]* (?:\s|$)/x
Input: +.0
Regex: /(?:^|\s)(?=\S*\d) [+-] [0]* [.]? [0]* (?:\s|$)/x
Input: -.0
Regex: /(?:^|\s)(?=\S*\d) [+-] [0]* [.]? [0]* (?:\s|$)/x
Input: 0.
Regex: /(?:^|\s)(?=\S*\d) [+-] [0]* [.]? [0]* (?:\s|$)/x
Input: -0.00100
Regex: /(?:^|\s)(?=\S*\d) [-] [0]* [.] 001[0]* (?:\s|$)/x
Input: 1
Regex: /(?:^|\s)(?=\S*\d) [+]? [0]*1 [.]? [0]* (?:\s|$)/x
Input: +.1
Regex: /(?:^|\s)(?=\S*\d) [+]? [0]* [.] 1[0]* (?:\s|$)/x
Input: +43.0910
Regex: /(?:^|\s)(?=\S*\d) [+]? [0]*43 [.] 091[0]* (?:\s|$)/x
Input: 22
Regex: /(?:^|\s)(?=\S*\d) [+]? [0]*22 [.]? [0]* (?:\s|$)/x
Input: 33.e19
**input '33.e19' is not valid
Here's a good tool for you to explore regular expressions :)
http://www.regular-expressions.info/javascriptexample.html
Adopted from the site above:
function demoShowMatchClick() {
var re = new RegExp("(?:^| )+(22(?:$| ))+");
var m = re.exec("22.5 98 12 22 322");
if (m == null) {
alert("No match");
} else {
var s = "Match at position " + m.index + ":\n";
for (i = 0; i < m.length; i++) {
s = s + m[i] + "\n";
}
alert(s);
}
}
This will give you all matches and requires the number to be seperated by beginning or end of string or a whitespace.