I have a string of the following format:
"hello(%npm%)hi"
My goal is to split the string into three parts
a) hello
b) (%npm%)
c) hi
I am using regex as follows:
var myString = "hello(%npm%)hi".match(/[a-z]*/);
var backdtring = "hello(%npm%)hi".match(/\)[a-z]*/);
var midstring = "hello(%npm%)hi".match(/\(\%[a-z]*\%\)/);
var res = backdtring.replace(")", "");
https://jsfiddle.net/1988/ff6aupmL/
I am trying in jsfiddle , where theres an error in the line:
var res = backdtring.replace(")", "");
"backdtring.replace is not a function" .
Whats wrong in the replace function above?
Update:
Also, have I used the best practices of regular expressions ?
As it has been mentioned in the comments, you are trying to use a String#replace method on an array, see the description of the return value of String#match:
An Array containing the entire match result and any parentheses-captured matched results; null if there were no matches.
To streamline tokenization, I'd rather use .split(/(\([^()]*\))/) to get all substrings in parentheses and the substrings that remain:
var s = "hello(%npm%)hi";
var res = s.split(/(\([^()]*\))/);
console.log(res);
Details:
(\([^()]*\)) - the pattern is enclosed with capturing group so as split could return both the substrings that match and those that do not match the pattern
\( -a literal (
[^()]* - 0+ chars other than ( and )
\) - a literal ).
Related
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.
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
I am using Javascript and currently looking for a way to match as many of my pattern's letters as possible, maintaining the original order..
For example a search pattern queued should return the march Queue/queue against the any of the following search strings:
queueTable
scheduledQueueTable
qScheduledQueueTable
As of now I've reached as far as this:
var myregex = new RegExp("([queued])", "i");
var result = myregex.exec('queueTable');
but it doesn't seem to work correctly as it highlights the single characters q,u,e,u,e and e at the end of the word Table.
Any ideas?
Generate the regex with optional non-capturing group part where regex pattern can be generate using Array#reduceRight method.
var myregex = new RegExp("queued"
.split('')
.reduceRight(function(str, s) {
return '(?:' + s + str + ')?';
}, ''), "i");
var result = myregex.exec('queueTable');
console.log(result)
The method generates regex : /(?:q(?:u(?:e(?:u(?:e(?:d?)?)?)?)?)?)?/
UPDATE : If you want to get the first longest match then use g modifier in regex and find out the largest using Array#reduce method.
var myregex = new RegExp(
"queued".split('')
.reduceRight(function(str, s) {
return '(?:' + s + str + ')?';
}, ''), "ig");
var result = 'qscheduledQueueTable'
.match(myregex)
.reduce(function(a, b) {
return a.length > b.length ? a : b;
});
console.log(result);
I think the logic would have to be something like:
Match as many of these letters as possible, in this order.
The only real answer that comes to mind is to get the match to continue if possible, but allow it to bail out. In this case...
myregex = /q(?:u(?:e(?:u(?:e(?:d|)|)|)|)|)/;
You can generate this, of course:
function matchAsMuchAsPossible(word) { // name me something sensible please!
return new RegExp(
word.split("").join("(?:")
+ (new Array(word.length).join("|)"))
);
}
You are using square brackets - which mean that it will match a single instance of any character listed inside.
There are a few ways of interpreting your intentions:
You want to match the word queue with an optional 'd' at the end:
var myregex = new RegExp("queued?", "i");
var result = myregex.exec('queueTable');
Note this can be shorter try this:
'queueTable'.match(/queued?/i);
I also removed the brackets as these were not adding anything here.
This link provides some good examples that may help you further: https://www.w3schools.com/js/js_regexp.asp
When you use [] in a regular expression, it means you want to match any of the characters inside the brackets.
Example: if I use [abc] it means "match a single character, and this character can be 'a', 'b' or 'c'"
So in your code [queued] means "match a single character, and this character can be 'q', 'u', 'e' or 'd'" - note that 'u' and 'e' appear twice so they are redundant in this case. That's why this expression matches just one single character.
If you want to match the whole string "queued", just remove the brackets. But in this case it won't match, because queueTable doesn't have 'd'. If you want 'd' to be optional, you can use queued? as already explained in previous answers.
Try something like the following :
var myregex = /queued?\B/g;
var result = myregex.exec('queueTable');
console.log(result);
I have regexp that extracts values between parentheses.
It's working most of the time but not when it ends with a parentheses
var val = 'STR("ABC(t)")';
var regExp = /\(([^)]+)\)/;.
var matches = regExp.exec(val);
console.log(matches[1]); //"ABC(t"
What I want is "ABC(t)".
Any ideas how I can modify my regexp to Achive this?
Update
The value is always inside the parentheses.
Some examples:
'ASD("123")'; => '123'
'ASD(123)'; => '123'
'ASD(aa(10)asda(459))'; => 'aa(10)asda(459)'
So first there is some text (always text). Then there is a (, and it always ends with a ). I want the value between.
You may use greedy dot matching inside Group 1 pattern: /\((.+)\)/. It will match the first (, then any 1+ chars other than linebreak symbols and then the last ) in the line.
var vals = ['STR("ABC(t)")', 'ASD("123")', 'ASD(123)', 'ASD(aa(10)asda(459))'];
var regExp = /\((.+)\)/;
for (var val of vals) {
var matches = regExp.exec(val);
console.log(val, "=>", matches[1]);
}
Answering the comment: If the texts to extract must be inside nested balanced parentheses, either a small parsing code, or XRegExp#matchRecursive can help. Since there are lots of parsing codes around on SO, I will provide XRegExp example:
var str = 'some text (num(10a ) ss) STR("ABC(t)")';
var res = XRegExp.matchRecursive(str, '\\(', '\\)', 'g');
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/xregexp/2.0.0/xregexp-all-min.js"></script>
I have the following string: pass[1][2011-08-21][total_passes]
How would I extract the items between the square brackets into an array? I tried
match(/\[(.*?)\]/);
var s = 'pass[1][2011-08-21][total_passes]';
var result = s.match(/\[(.*?)\]/);
console.log(result);
but this only returns [1].
Not sure how to do this.. Thanks in advance.
You are almost there, you just need a global match (note the /g flag):
match(/\[(.*?)\]/g);
Example: http://jsfiddle.net/kobi/Rbdj4/
If you want something that only captures the group (from MDN):
var s = "pass[1][2011-08-21][total_passes]";
var matches = [];
var pattern = /\[(.*?)\]/g;
var match;
while ((match = pattern.exec(s)) != null)
{
matches.push(match[1]);
}
Example: http://jsfiddle.net/kobi/6a7XN/
Another option (which I usually prefer), is abusing the replace callback:
var matches = [];
s.replace(/\[(.*?)\]/g, function(g0,g1){matches.push(g1);})
Example: http://jsfiddle.net/kobi/6CEzP/
var s = 'pass[1][2011-08-21][total_passes]';
r = s.match(/\[([^\]]*)\]/g);
r ; //# => [ '[1]', '[2011-08-21]', '[total_passes]' ]
example proving the edge case of unbalanced [];
var s = 'pass[1]]][2011-08-21][total_passes]';
r = s.match(/\[([^\]]*)\]/g);
r; //# => [ '[1]', '[2011-08-21]', '[total_passes]' ]
add the global flag to your regex , and iterate the array returned .
match(/\[(.*?)\]/g)
I'm not sure if you can get this directly into an array. But the following code should work to find all occurences and then process them:
var string = "pass[1][2011-08-21][total_passes]";
var regex = /\[([^\]]*)\]/g;
while (match = regex.exec(string)) {
alert(match[1]);
}
Please note: i really think you need the character class [^\]] here. Otherwise in my test the expression would match the hole string because ] is also matches by .*.
'pass[1][2011-08-21][total_passes]'.match(/\[.+?\]/g); // ["[1]","[2011-08-21]","[total_passes]"]
Explanation
\[ # match the opening [
Note: \ before [ tells that do NOT consider as a grouping symbol.
.+? # Accept one or more character but NOT greedy
\] # match the closing ] and again do NOT consider as a grouping symbol
/g # do NOT stop after the first match. Do it for the whole input string.
You can play with other combinations of the regular expression
https://regex101.com/r/IYDkNi/1
[C#]
string str1 = " pass[1][2011-08-21][total_passes]";
string matching = #"\[(.*?)\]";
Regex reg = new Regex(matching);
MatchCollection matches = reg.Matches(str1);
you can use foreach for matched strings.