string = '1,23'
When a comma is present in the string, I want the regex to match the first digit (\n) after the comma e.g.2.
Sometimes the comma will not be there. When it's not present, I want the regex to match the first digit of the string e.g. 1.
Also, we can't reverse the order of the string to solve this task.
I am genuinely stuck. The only idea I had was prepending this: [,|nothing]. I tried '' to mean nothing but that didn't work.
You can match an optional sequence of chars other than a comma and then a comma at the start of a string, and then match and capture the digit with
/^(?:[^,]*,)?(\d)/
See the regex demo.
Details
^ - start of string
(?:[^,]*,)? - an optional sequence of
[^,]* - 0 any chars other than a comma
, - a comma
(\d) - Capturing group 1: any digit
See the JavaScript demo:
const strs = ['123', '1,23'];
const rx = /^(?:[^,]*,)?(\d)/;
for (const s of strs) {
const result = (s.match(rx) || ['',''])[1];
// Or, const result = s.match(rx)?.[1] || "";
console.log(s, '=>', result);
}
Related
I'm trying to write a regex function that return all of the digits in a comma separated string:
function printDigits() {
var result = sentence.replace(/[^0-9]/g, '').split(",")
console.log(result)
}
But it just prints out a string instead of digits being separated by comma. Are there any ways I can fix this?
Input: "5om3 wr173 w0rd5 u51n9 numb3r5."
Expected output: "5,3,1,7,3,0,5,5,1,9,3,5"
split doesn't work this way. It splits by the separator that is already in the input. To split string to individual characters use split(''), and then join individual characters with comma:
var result = sentence.replace(/[^0-9]/g, '').split('').join(',');
You can use
sentence.match(/\d/g).join(",")
Here,
sentence.match(/\d/g) - extracts each separate digit from string
.join(",") - join the array items into a single comma-delimited string.
See the JavaScript demo:
var sentence = "5om3 wr173 w0rd5 u51n9 numb3r5.";
console.log(sentence.match(/\d/g).join(","));
// -> 5,3,1,7,3,0,5,5,1,9,3,5
Here's another variation that uses pure regex and does not require a .join() call:
sentence.replace(/\D+|(\d)(?=\d)/g, '$1,');
This replaces any string of non-digit characters with a comma. And it also locates the position between two digits and adds a comma between them.
Pattern breakdown:
\D+ - Match one or more non-digit characters.
| - OR...
(\d) - Match one digit and capture it in group 1.
(?=\d) - Followed by another digit.
Substition:
$1, - Replace with whatever was captured in group 1, plus a comma.
Here's a full demo:
var sentence = "5om3 wr173 w0rd5 u51n9 numb3r5";
var result = sentence.replace(/\D+|(\d)(?=\d)/g, '$1,');
console.log(result); // 5,3,1,7,3,0,5,5,1,9,3,5
A reducer solution
const x = `5om3 wr173 w0rd5 u51n9 numb3r5`
.split('')
.reduce((acc, val) =>
val.trim().length && !isNaN(+val) ? [...acc, +val] : acc, []);
console.log(`${x}`);
Or simply
console.log(`${`5om3 wr173 w0rd5 u51n9 numb3r5`.match(/\d/g)}`);
Example data expected output
sds-rwewr-dddd-cash0-bbb cash0
rrse-cash1-nonre cash1
loan-snk-cash2-ssdd cash2
garb-cash3-dfgfd cash3
loan-unwan-cash4-something cash4
The common pattern is here, need to extract a few chars before the last hyphen of given string.
var regex1= /.*(?=(?:-[^-]*){1}$)/g ; //output will be "ds-rwewr-dddd-cash0" from "sds-rwewr-dddd-cash0-bbb "
var regex2 = /\w[^-]*$/g ; //output will be "cash0" from "ds-rwewr-dddd-cash0"
var res =regex2.exec(regex1.exec(sds-rwewr-dddd-cash0-bbb)) //output will cash0
Although above nested regex is working as expected but may not be optimize one. So any help will be appreciated for optimized regex
You can use
/\w+(?=-[^-]*$)/
If the part before the last hyphen can contain chars other than word chars, keep using \w[^-]*: /\w[^-]*(?=-[^-]*$)/. If you do not need to check the first char of your match, simply use /[^-]+(?=-[^-]*$)/.
See the regex demo.
Details:
\w+ - one or more word chars
(?=-[^-]*$) - that must be followed with - and then zero or more chars other than - till the end of string.
JavaScript demo
const texts = ['sds-rwewr-dddd-cash0-bbb','rrse-cash1-nonre','loan-snk-cash2-ssdd','garb-cash3-dfgfd','loan-unwan-cash4-something'];
const regex = /\w+(?=-[^-]*$)/;
for (var text of texts) {
console.log(text, '=>', text.match(regex)?.[0]);
}
There is such line
let str = 'ds 1,2abc{3,4}dd'
I need to find numbers that will be included in {} without enclosing the brackets themselves.
For example (Assuming that regex is a per-defined regular expression) I want to write something like the following.
(str.match(regexp)).join('').split(',')
Which will produce a result like this => ['3','4']
and if I have only one char in brackets or char with comma I need to get next result
let str = 'ds 1,2abc{3,}dd'
(str.match(regexp)).join('').split(',') => ['3','']
At the moment, I have such a regular const regexp = (/\d+\,\d*|(?<=\{)\d+/
but it does not handle the case when there are more numbers in the string with a comma like 1,2
It seems you are actually trying to include an empty string in your resulting array. Maybe you could use:
var str = 'ds 1,2abc{3,4}dd';
var res = str.split(/[{}]/)[1].split(",");
console.log(res)
var str = 'ds 1,2abc{3,}dd';
var res = str.split(/[{}]/)[1].split(",");
console.log(res)
The usual workaround, when the number of open/close curly braces is matching and you need not pre-validate your input, you may simply use
str.match(/\d+(?:\.\d+)?(?=[^{}]*})/g)
str.match(/\d*\.?\d+(?=[^{}]*})/g)
Here, \d+(?:\.\d+)?(?=[^{}]*}) matches 1+ digits, followed with an optional sequence of a dot and 1+ digits followed with 0 or more chars other than { and } and then a }.
See this demo
In a more generic case, you may extract groups of numbers inside curly braces by matching curly braces with comma-separated numbers in them first. Then, you may extract the numbers from each match:
const str = 'ds 1,2abc{3,4}dd{not this one 5,6} and {7,8.666,9,10.45}';
const rx = /{\d*\.?\d+(?:,\d*\.?\d+)*}/g;
const results = str.match(rx).map(x => x.replace(/[{}]+/g,'').split(','));
console.log( results );
See the regex demo.
{ - a { char
\d*\.?\d+ - 0 or more digits followed with an optional . and then 1+ digits
(?:,\d*\.?\d+)* - 0 or more repetitions of a comma followed with 0 or more digits followed with an optional . and then 1+ digits
} - a { char.
I need to parse a string that comes like this:
-38419-indices-foo-7119-attributes-10073-bar
Where there are numbers followed by one or more words all joined by dashes. I need to get this:
[
0 => '38419-indices-foo',
1 => '7119-attributes',
2 => '10073-bar',
]
I had thought of attempting to replace only the dash before a number with a : and then using .split(':') - how would I do this? I don't want to replace the other dashes.
Imo, the pattern is straight-forward:
\d+\D+
To even get rid of the trailing -, you could go for
(\d+\D+)(?:-|$)
Or
\d+(?:(?!-\d|$).)+
You can see it here:
var myString = "-38419-indices-foo-7119-attributes-10073-bar";
var myRegexp = /(\d+\D+)(?:-|$)/g;
var result = [];
match = myRegexp.exec(myString);
while (match != null) {
// matched text: match[0]
// match start: match.index
// capturing group n: match[n]
result.push(match[1]);
match = myRegexp.exec(myString);
}
console.log(result);
// alternative 2
let alternative_results = myString.match(/\d+(?:(?!-\d|$).)+/g);
console.log(alternative_results);
Or a demo on regex101.com.
Logic
lazy matching using quantifier .*?
Regex
.*?((\d+)\D*)(?!-)
https://regex101.com/r/WeTzF0/1
Test string
-38419-indices-foo-7119-attributes-10073-bar-333333-dfdfdfdf-dfdfdfdf-dfdfdfdfdfdf-123232323-dfsdfsfsdfdf
Matches
Further steps
You need to split from the matches and insert into your desired array.
I am trying to capture all characters between multiple instances of asterisks, which are comma delimited in a string. Here's an example of the string:
checkboxID0*,*checkboxID1*,&checkboxID2&,*checkboxID3*,!checkboxID4!,checkboxID5*
The caveat is that the phrase must start and end with an asterisk. I have been able to come close by using the following regex, however, it won't discard any matches when the captured string is missing the starting asterisk(*):
let str = "checkboxID0*,*checkboxID1*,&checkboxID2&,*checkboxID3*,!checkboxID4!,checkboxID5*"
const regex = /[^\,\*]+(?=\*)/gi;
var a = str.match(regex)
console.log(a) // answer should exclude checkboxID0 and checkboxID5
The answer returns the following, however, "checkboxID0 and checkboxID5" should be excluded as it doesn't start with an asterisk.
[
"checkboxID0",
"checkboxID1",
"checkboxID3",
"checkboxID5"
]
Thanks, in advance!
You need to use asterisks on both ends of the pattern and capture all 1 or more chars other than commas and asterisks in between:
/\*([^,*]+)\*/g
See the regex demo
Pattern details
\* - an asterisk
([^,*]+) - Capturing group 1: one or more chars other than , and *
\* - an asterisk
JS demo:
var regex = /\*([^,*]+)\*/g;
var str = "checkboxID0*,*checkboxID1*,&checkboxID2&,*checkboxID3*,!checkboxID4!,checkboxID5*";
var m, res = [];
while (m = regex.exec(str)) {
res.push(m[1]);
}
console.log(res);