I need your help as I'm stuck on a regular expression.
The regular expression needs to match any characters but the first number.
This first number can be an integer, negative, decimal.
so I have the RegExp for that:
var b = /[-]?[0-9]+([\.][0-9]+)?/;
but when I do that in JavaScript:
var a = 'ab123ab45',
b = /[-]?[0-9]+([\.][0-9]+)?/;
a.replace(b, '');
it obviously return: abab45
But what I need, as you may understood, is the other way around.
Here are some examples.
123 -> 123
123a -> 123
a123a -> 123
123ab45 -> 123
ab123ab45 -> 123
a1b2c3 -> 1
a1.2b -> 1.2
a1,2b -> 1
And I need to get that using only 1 regular expression with the replace function.
If you need it with replace (not with match):
var a = 'ab123ab45',
b = /.*?([-]?[0-9]+([\.][0-9]+)?).*/;
a.replace(b, '$1');
Try:
m = a.match(b);
console.log(m[0]);
Try this;
var a = "a1b2c3";
a = a.replace(/^.*?([.,\d]+).*?$/, "$1");
alert(a);
LIVE DEMO
Regex Explanation
^.*?([.,\d]+).*?$
Assert position at the beginning of the string «^»
Match any single character that is not a line break character «.*?»
Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
Match the regular expression below and capture its match into backreference number 1 «([.,\d]+)»
Match a single character present in the list below «[.,\d]+»
Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
One of the characters “.,” «.,»
A single digit 0..9 «\d»
Match any single character that is not a line break character «.*?»
Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
Assert position at the end of the string (or before the line break at the end of the string, if any) «$»
Related
I have this line:
val = val.replace(/[^0-9\.]/g, '')
and it replaces anything that is not a number, but I need a regular expression that limits val to be 2 numbers, period and then 2 numbers, like this:
- 11.33
- 12.34
- 54.65
I've already tried something like this but it didn't work:
val = val.replace(/^[^0-9\.]{1,2}/g, '')
Normally with replace you scan the entire string and keep the middle part. So start with beginning (^), scan some stuff you don't care about (.), then scan your number ([0-9]{1,2}(?:.[0-9]{0-2})?), then scan the rest which you don't care about (.), then you're at the end ($).
Then you replace with the middle capture group.
val.replace(/^(.*)([0-9]{1,2}(?:\.[0-9]{0-2})?)(.*)$/gm,'\2');
Use the m flag to process line by line.
Sometimes it is easier to use multiple regexes instead of one. Here is a solution that uses a first regex to strip the string from anything but number digits, then a second regex that reduces the number string to the proper length:
const regex1 = /[^\d\.]/g;
const regex2 = /^.*(\d\d\.\d\d).*$/;
[
'aaa11.33zzz',
'aaa123.456zzz',
'-54.65',
'12xtra.34'
].forEach(str => {
let result = str.replace(regex1, '').replace(regex2, '$1');
console.log(str, '==>', result);
});
Output:
aaa11.33zzz ==> 11.33
aaa123.456zzz ==> 23.45
-54.65 ==> 54.65
12xtra.34 ==> 12.34
Explanation of regex1:
[^\d\.] -- anything not 0-9 and .
g -- flag to replace pattern multiple times
Explanation of regex2:
^ -- anchor at start of string
.* -- greedy scan
(\d\d\.\d\d) -- expect 2 digits, a dot, and 2 digits
.* -- greedy scan
$ -- anchor at end of string
You did not specify what should happen if the input string has less than the 2digits, dot, 2 digits pattern. So this solution does not address that case.
I have the string:
"Vl.55.16b25.3d.42b50.59b30.90.24b35.3d.56.67b70.Tv.54b30.Vl.41b35.Tv.Bd.71b50.3d.99b20.03b50.Tv.73b50.Vl.05b25.12b40.Bd.Tv.82b25."
How to detached get results like:
["Vl.55.16b25", 3d.42.b50.59b30.90.24b35, 3d.56.67b70, ...]
The logic:
Condition 1: The End will be start b and 2 number. Example: b20, b25.
If pass condition 1 I need to check condition 2.
Condition 2: maybe like "3d" or 2 characters. If don't match condition 2 we need to pass the next character to the current block.
Many thanks.
If I understand your question correctly, the following code should work:
var string = "Vl.55.16b25.3d.42b50.59b30.90.24b35.3d.56.67b70.Tv.54b30.Vl.41b35.Tv.Bd.71b50.3d.99b20.03b50.Tv.73b50.Vl.05b25.12b40.Bd.Tv.82b25.";
console.log(string.split(/(?<=b\d\d)\.(?=3d)/g))
Explanation:
(?<=) is look-behind.
b matches the literal character "b".
\d matches any digit so \d\d will match two digits in a row.
\. matches a literal ".", it needs the \ before it because otherwise it would match any character.
(?=) is look-ahead.
The g flag stands for global so the string will be split up at every occurrence of the regular expression.
This means that the string will be split at every occurrence of "." that is preceded the letter "b" then two digits, and followed by "3d".
Assuming you want to separate by last having 'b' and two digits followed by 3d, two digits or the end of string (this is necessary) and by omitting leading dot, you could take the following regular expression.
const
string = "Vl.55.16b25.3d.42b50.59b30.90.24b35.3d.56.67b70.Tv.54b30.Vl.41b35.Tv.Bd.71b50.3d.99b20.03b50.Tv.73b50.Vl.05b25.12b40.Bd.Tv.82b25.",
result = string.match(/[^.].*?b\d\d(?=\.(3d|\D\D|$))/g);
console.log(result);
This is not a duplicate, the linked thread does not explain how to achieve this.
I'm looking to get a phone number in a specific format.
+xx (x) xxx xxx xxxx
Country code.
Space.
Zero in brackets.
Space.
3 digits.
Space.
3 digits.
Space.
4 digits.
The user could type anything in (but should always be a +61 number). So far I have tried the below.
Removing spaces and non numeric characters.
If starting with a zero, remove.
If starting with 610, remove.
If starting with 61, remove.
Re add country code in specific format and format rest of phone number is a 3,3,4 format.
My question, is - is there a way to simply the below to perhaps one expression?
value = value.replace(/\D/g,'');
value = value.startsWith(0) ? value.substring(1) : value;
value = value.startsWith('610') ? value.substring(3) : value;
value = value.startsWith('61') ? value.substring(2) : value;
value = '+61 (0) ' + value.replace(/\d{3,4}?(?=...)/g, '$& ');
To expand and explain on #splash58's comment they propose using two regular expressions to do the full replacement you desire. The first(/\D|(0+|610|61)/gi) will remove all unwanted characters within the string. The second (/(\d{3})(\d{3})(\d{4})/gi) will take the remaining digits and capture the desired groupings so you can format them as desired. I highly suggest looking at the regex101 links they provided as that site will fully explain how and why a given expressions matches what it does on the right.
Short version:
/\D|(0+|610|61)/gi will match any NON-digit character OR a string of 0s, "610" or "61". Replace this with nothing to remove
/(\d{3})(\d{3})(\d{4})/gi will match a string of 10 digits and capture groups, that's what the parentheses are, of 3 digits, 3 digits and 4 digits. These can be referenced in the replacement as identifiers $1, $2 and $3 according to their position.
Putting it all together:
// look in a string and return formatted phone number only
function phone(str) {
str = str.replace(/\D|(0+|610|61)/gi, '');
str = str.replace(/(\d{3})(\d{3})(\d{4})/gi, '+61 (0) $1 $2 $3');
return str;
}
console.log(phone('xgsh6101231231234vvajx'));
console.log(phone('+6101231231234'));
I would also recommend first doing a search on the entire input string for a series of numbers or whitespace so that you end up with less false positives. This can be done with a regular expression like /[\d\s]+/
You might match the number using:
^.*?\+?0*610?(\d{3})(\d{3})(\d{4})(?!\d).*$
Regex demo
And replace with:
+61 (0) $1 $2 $3
Explanation
^ Assert the start of the string
.*? Match 0+ characters non greedy
\+? Match an optional plus sign
0*610? Match 0+ times a zero, 61 with optional zero
(\d{3})(\d{3})(\d{4}) match 3 groups with 3, 3, and 4 digits
(?!\d) Negative lookahead to assert what follows is not a digit
.* Match 0+ characters
$ Assert the end of the string
const strings = [
"xgsh6101231231234vvajx",
"xgsh06101231231234vvajx",
"xgsh000006101231231234vvajx",
"+6101231231234",
"xgsh61012312312345vvajx",
"xgsh5101231231234vvajx",
"xgsh00000101231231234vvajx",
"xgsh6143545626455345601231231234vvajx"
];
let pattern = /^.*?\+?0*610?(\d{3})(\d{3})(\d{4})(?!\d).*$/;
strings.forEach((s) => {
console.log(s.replace(pattern, "+61 (0) $1 $2 $3"));
});
This is from an exercise on FCC beta and i can not understand how the following code means two consecutive numbers seeing how \D* means NOT 0 or more numbers and \d means number, so how does this accumulate to two numbers in a regexp?
let checkPass = /(?=\w{5,})(?=\D*\d)/;
This does not match two numbers. It doesn't really match anything except an empty string, as there is nothing preceding the lookup.
If you want to match two digits, you can do something like this:
(\d)(\d)
Or if you really want to do a positive lookup with the (?=\D*\d) section, you will have to do something like this:
\d(?=\D*\d)
This will match against the last digit which is followed by a bunch of non-digits and a single digit. A few examples (matched numbers highlighted):
2 hhebuehi3
^
245673
^^^^^
2v jugn45
^ ^
To also capture the second digit, you will have to put brackets around both numbers. Ie:
(\d)(?=\D*(\d))
Here it is in action.
In order to do what your original example wants, ie:
number
5+ \w characters
a non-number character
a number
... you will need to precede your original example with a \d character. This means that your lookups will actually match something which isn't just an empty string:
\d(?=\w{5,})(?=\D*\d)
IMPORTANT EDIT
After playing around a bit more with a JavaScript online console, I have worked out the problem with your original Regex.
This matches a string with 5 or more characters, including at least 1 number. This can match two numbers, but it can also match 1 number, 3 numbers, 12 numbers, etc. In order to match exactly two numbers in a string of 5-or-more characters, you should specify the number of digits you want in the second half of your lookup:
let regex = /(?=\w{5,})(?=\D*\d{2})/;
let string1 = "abcd2";
let regex1 = /(?=\w{5,})(?=\D*\d)/;
console.log("string 1 & regex 1: " + regex1.test(string1));
let regex2 = /(?=\w{5,})(?=\D*\d{2})/;
console.log("string 1 & regex 2: " + regex2.test(string1));
let string2 = "abcd23";
console.log("string 2 & regex 2: " + regex2.test(string2));
My original answer was about Regex in a vacuum and I glossed over the fact that you were using Regex in conjunction with JavaScript, which works a little differently when comparing Regex to a string. I still don't know why your original answer was supposed to match two numbers, but I hope this is a bit more helpful.
?= Positive lookahead
w{5,} matches any word character (equal to [a-zA-Z0-9_])
{5,}. matches between 5 and unlimited
\D* matches any character that\'s not a digit (equal to [^0-9])
* matches between zero and unlimited
\d matches a digit (equal to [0-9])
This expression is global - so tries to match all
You can always check your expression using regex101
I'm trying to write code that removes all after the first block of numbers and text.Do you have any idea how to do this.
string = '009EPMT18$MBS'
the expected result
string = '009EPMT'
You'll need regex to do that. It's a string analysis syntax common in many languages. There are many regular expressions which would do what you want, here's one:
var myRegex = /^[0-9]+[a-zA-Z]+/;
^ means that the search must begin at the start of the string.
[0-9] means that right after the beginning, there must be characters in the 0 to 9 range.
+ means there must be one or more of the previous condition, meaning there must be one or more digits.
[a-zA-Z] means there must be any character in the range a to z or A to Z. This won't include accented characters and letters from other alphabets though.
Calling .exec(string) on a regex returns an array of found strings in the passed string.
You were on the right track, the letters were just missing from your pattern:
var s = '009EPMT18$MBS';
var result;
var m = s.match(/^\d+[A-Z]+/); // first numbers and uppercase text
if (m) result = m[0]; // result = "009EPMT"
Regex explanation: beginning of string ^ followed by 1 or more digits \d+ followed by 1 or more letters from A to Z [A-Z]+. Note that lowercase characters will not match.