How can I get the strings between last 2 slashes in regex in javascript?
for example:
stackoverflow.com/questions/ask/index.html => "ask"
http://regexr.com/foo.html?q=bar => "regexr.com"
https://www.w3schools.com/icons/default.asp => "icons"
You can use /\/([^/]+)\/[^/]*$/; [^/]*$ matches everything after the last slash, \/([^/]+)\/ matches the last two slashes, then you can capture what is in between and extract it:
var samples = ["stackoverflow.com/questions/ask/index.html",
"http://regexr.com/foo.html?q=bar",
"https://www.w3schools.com/icons/default.asp"]
console.log(
samples.map(s => s.match(/\/([^/]+)\/[^/]*$/)[1])
)
You can solve this by using split().
let a = 'stackoverflow.com/questions/ask/index.html';
let b = 'http://regexr.com/foo.html?q=bar';
let c = 'https://www.w3schools.com/icons/default.asp';
a = a.split('/')
b = b.split('/')
c = c.split('/')
indexing after split()
console.log(a[a.length-2])
console.log(b[b.length-2])
console.log(c[c.length-2])
I personally do not recommend using regex. Because it is hard to maintain
I believe that will do:
[^\/]+(?=\/[^\/]*$)
[^\/]+ This matches all chars other than /. Putting this (?=\/[^\/]*$) in the sequence looks for the pattern that comes before the last /.
var urls = [
"stackoverflow.com/questions/ask/index.html",
"http://regexr.com/foo.html?q=bar",
"https://www.w3schools.com/icons/default.asp"
];
urls.forEach(url => console.log(url.match(/[^\/]+(?=\/[^\/]*$)/)[0]));
You can use (?=[^/]*\/[^/]*$)(.*?)(?=\/[^/]*$). You can test it here: https://www.regexpal.com/
The format of the regex is: (positive lookahead for second last slash)(.*?)(positive lookahead for last slash).
The (.*?) is a lazy match for what's between the slashes.
references:
Replace second to last "/" character in URL with a '#'
RegEx that will match the last occurrence of dot in a string
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)}`);
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.
Examples of filenames
FDIP_en-gb-nn_Text_v1_YYYYMMDD_SequenceNumber.txt
FDIP_fr-fr-nn_Text_v1_YYYYMMDD_SequenceNumber.txt
FDIP_de-de-nn_Text_v1_YYYYMMDD_SequenceNumber.txt
REGEX is FDIP_([a-z]{2}-[A-Z]{2}-[a-z]{2})_Text_v1_[0-9]{8}_[0-9]{14}.txt
The only part I need is the translation code which is 'en-gb', 'fr-fr' , 'de-de.
How do I extract just that part of the filename?
Modified the regex little bit to match the numbers and text. You can play around here
Explanation
to capture a group you need to wrap the regex into () this will capture as a group.
to do the named capturing you can (?<name_of_group>) and then you can access by name.
Here goes the matching process.
[a-z]{2} match 2 char from a-z
[a-zA-Z0-9] match any char of a-z or A-Z or 0-9
g means global flag i.e. match all.
i means ignore case.
var r = /FDIP_([a-z]{2}-[A-Z]{2})-[a-z]{2}_Text_v1_[0-9A-Z]{8}_[A-Z0-9]{14}.txt/gi;
let t = 'FDIP_en-gb-nn_Text_v1_YYYYMMDD_SequenceNumber.txt';
let dd = r.exec(t);
console.log(dd[1]);
This is example of group capturing
See the name in the regex and the object destructing name is matching.
const { groups: { language } } = /FDIP_(?<language>[a-z]{2}-[A-Z]{2})-[a-z]{2}_Text_v1_[0-9A-Z]{8}_[A-Z0-9]{14}.txt/gi.exec('FDIP_en-gb-nn_Text_v1_YYYYMMDD_SequenceNumber.txt');
console.log(language);
To solve your problem, you should:
Fix your regex:
FDIP_([a-z]{2}-[A-Z]{2}-[a-z]{2})_Text_v1_[0-9]{8}_[0-9]{14}.txt
// to
FDIP_([a-z]{2}-[a-z]{2})-[a-z]{2}_Text_v1_[0-9]{8}_[0-9]{14}.txt
Use get value from first group by using regex.exec function
const fileNames = [
'FDIP_en-gb-nn_Text_v1_20190101_12345678901234.txt',
'FDIP_fr-fr-nn_Text_v1_20200202_12345678901234.txt',
'FDIP_de-de-nn_Text_v1_20180808_12345678901234.txt']
const cultureNames = fileNames.map(name => {
const matched = /FDIP_([a-z]{2}-[a-z]{2})-[a-z]{2}_Text_v1_[0-9]{8}_[0-9]{14}.txt/.exec(name)
return matched && matched[1]
})
console.log(cultureNames)
Change FDIP_([a-z]{2}-[A-Z]{2}-[a-z]{2})_Text_v1_[0-9]{8}_[0-9]{14}.txt
to
let pattern = /FDIP_([a-z]{2}-[a-z]{2})-[a-z]{2}_Text_v1_[\w]{8}_[\w]{14}.txt/;
var str = 'FDIP_en-gb-nn_Text_v1_YYYYMMDD_SequenceNumber.txt';
console.log(str.match(pattern)[1]);
I have problem with simple rexex. I have example strings like:
Something1\sth2\n649 sth\n670 sth x
Sth1\n\something2\n42 036 sth\n42 896 sth y
I want to extract these numbers from strings. So From first example I need two groups: 649 and 670. From second example: 42 036 and 42 896. Then I will remove space.
Currently I have something like this:
\d+ ?\d+
But it is not a good solution.
You can use
\n\d+(?: \d+)?
\n - Match new line
\d+ - Match digit from 0 to 9 one or more time
(?: \d+)? - Match space followed by digit one or more time. ( ? makes it optional )
let strs = ["Something1\sth2\n649 sth\n670 sth x","Sth1\n\something2\n42 036 sth\n42 896 sth y"]
let extractNumbers = str => {
return str.match(/\n\d+(?: \d+)?/g).map(m => m.replace(/\s+/g,''))
}
strs.forEach(str=> console.log(extractNumbers(str)))
If you need to remove the spaces. Then the easiest way for you to do this would be to remove the spaces and then scrape the numbers using 2 different regex.
str.replace(/\s+/, '').match(/\\n(\d+)/g)
First you remove spaces using the \s token with a + quantifier using replace.
Then you capture the numbers using \\n(\d+).
The first part of the regex helps us make sure we are not capturing numbers that are not following a new line, using \ to escape the \ from \n.
The second part (\d+) is the actual match group.
var str1 = "Something1\sth2\n649 sth\n670 sth x";
var str2 = "Sth1\n\something2\n42 036 sth\n42 896 sth y";
var reg = /(?<=\n)(\d+)(?: (\d+))?/g;
var d;
while(d = reg.exec(str1)){
console.log(d[2] ? d[1]+d[2] : d[1]);
}
console.log("****************************");
while(d = reg.exec(str2)){
console.log(d[2] ? d[1]+d[2] : d[1]);
}
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);