Get current matching regex-rule - javascript

I try to check for a given RegExp-rule in a string and need to get the current matching rule.
Here's what I've tried so far:
var prefixes = /-webkit-|-khtml-|-moz-|-ms-|-o-/g;
var match;
var str = '';
while ( !(match = prefixes.exec(str)) ) {
str += '-webkit-';
console.log(match); // => null
}
The match is null, but how can I get the current matching-rule (in this case -webkit-)?

var prefixes = /(-webkit-|-khtml-|-moz-|-ms-|-o-)/g;
var str = "-webkit-adsf-moz-adsf"
var m;
while(m = prefixes.exec(str))
console.log(m[0]);

You aren't asking for any groups in your regex, try surrounding your regex in parenthesis to define a group, e.g. /(-webkit-|-khtml-|-moz-|-ms-|-o-)/g.
Various other issues, try:
var prefixes = /(-webkit-|-khtml-|-moz-|-ms-|-o-)/g;
var match;
var str = 'prefix-ms-something';
match = prefixes.exec(str);
console.log(match);

Related

I have to make a split function in JavaScript

Edit
sorry if the question wasn't clear
here is the question..
create your version of javascript split function,
you may use indexOf and substring to help.
so if i give you a string "heellloolllloolllo" and i want to remove "llll" the function should return "heellloooolllo"
This what I did so far:
function split() {
var entered_string = document.forms["form1"]["str"].value;
var deleted_char = document.forms["form1"]["char"].value;
var index = entered_string.indexOf(deleted_char);
var i = deleted_char.length;
var result;
var x ;
for (x = 0; x< entered_string.length; x++ )
{
if (index < 0) {
result = entered_string;
} else {
result = entered_string.substring(0, index) +entered_string.substring(index+i);
}
}
alert(result)
}
Use the replace() function with the g at the end of your regular expression. It's called a "global modifier".
var string = 'heellloolllloolllo';
var res = string.replace(/llll/g, '');
console.log(res)
If your substring is a variable then you need to construct a new Regex object and set the g as the second parameter.
var string = 'heellloolllloolllo';
var find = 'llll';
var regex = new RegExp(find,'g');
var res = string.replace(regex, '');
console.log(res)
There are other useful modifiers you can use:
g - Global replace. Replace all instances of the matched string in the provided text.
i - Case insensitive replace. Replace all instances of the matched string, ignoring differences in case.
m - Multi-line replace. The regular expression should be tested for matches over multiple lines.
See this post for more information, credit to #codejoe.
Using String#replace and RegExp (the clean way)
var str = 'llllheellloolllloolllollll';
var matchStr = 'llll';
function removeSubString(str, matchStr) {
var re = new RegExp(matchStr, 'g');
return str.replace(re,"");
}
console.log(removeSubString(str, matchStr));
Using String#indexOf and String#substring
var str = 'llllheellloolllloolllollll';
var matchStr = 'llll';
function removeSubString(str, matchStr) {
var index = str.indexOf(matchStr);
while(index != -1) {
var firstSubStr = str.substring(0, index);
var lastSubStr = str.substring(index + matchStr.length);
str = firstSubStr + lastSubStr;
index = str.indexOf(matchStr);
}
return str;
}
console.log(removeSubString(str,matchStr))

Replace capture group content in JavaScript

In my JavaScript code I have a regular expression with capture groups (that is configured by library user) and a source string which matches this regular expression. The regular expression matches whole string (i.e. it has ^ and $ characters at its start and end).
A silly example:
var regex = /^([a-zA-Z]{2})-([0-9]{3})_.*$/;
var sourceStr = "ab-123_foo";
I want to reassemble the source string, replacing values in the capture groups and leaving the rest of the string intact. Note that, while this example has most of the "rest of the string" at its end, it actually may be anywhere else.
For example:
var replacements = [ "ZX", "321" ];
var expectedString = "ZX-321_foo";
Is there a way to do this in JavaScript?
NB: The regular expression is configured by the library user via the legacy API. I can not ask user to provide a second regular expression to solve this problem.
Without changing the regex the best I can think of is a callback that replaces the matches
sourceStr = sourceStr.replace(regex, function(match, $1, $2, offset, str) {
return str.replace($1, replacements[0]).replace($2, replacements[1]);
});
That's not a very good solution, as it would fail on something like
var sourceStr = "ab_ab-123_foo";
as it would replace the first ab instead of the matched one etc. but works for the given example and any string that doesn't repeat the matched characters
var regex = /^([a-zA-Z]{2})-([0-9]{3})_.*$/;
var sourceStr = "ab-123_foo";
var replacements = [ "ZX", "321" ];
sourceStr = sourceStr.replace(regex, function(match, $1, $2, offset, str) {
return str.replace($1, replacements[0]).replace($2, replacements[1]);
});
document.body.innerHTML = sourceStr;
I think this is close. It satisfies the two test cases but I'm unsure about leading and trailing groupings.
function replacer (regex, sourceStr, replacements) {
// Make a new regex that adds groups to ungrouped items.
var groupAll = "";
var lastIndex = 0;
var src = regex.source;
var reGroup=/\(.*?\)/g;
var match;
while(match = reGroup.exec(src)){
groupAll += "(" + src.substring(lastIndex, match.index) + ")";
groupAll += match[0];
lastIndex = match.index + match[0].length;
}
var reGroupAll = new RegExp(groupAll);
// Replace the original groupings with the replacements
// and append what was previously ungrouped.
var rep = sourceStr.replace(reGroupAll, function(){
// (match, $1, $2, ..., index, source)
var len = arguments.length - 2;
var ret = "";
for (var i = 1,j=0; i < len; i+=2,j++) {
ret += arguments[i];
ret += replacements[j];
}
return ret;
});
return rep;
}
var regex = /^([a-zA-Z]{2})-([0-9]{3})_.*$/;
var sourceStr = "ab-123_foo";
var replacements = [ "ZX", "321" ];
var expectedString = "ZX-321_foo";
var replaced = replacer(regex, sourceStr, replacements);
console.log(replaced);
console.log(replaced === expectedString);
regex = /^.*_([a-zA-Z]{2})-([0-9]{3})$/;
sourceStr = "ab_ab-123";
expectedString = "ab_ZX-321";
var replaced = replacer(regex, sourceStr, replacements);
console.log(replaced);
console.log(replaced === expectedString);
Output:
ZX-321_foo
true
ab_ZX-321
true

Javascript regex to extract variables

I have a string in Javascript that contains variables with the format ${var-name}. For example:
'This is a string with ${var1} and ${var2}'
I need to get these variables in an array: ['var1','var2'].
Is this possible with regex?
Have a try with:
/\$\{(\w+?)\}/
Running example, many thanks to #RGraham :
var regex = new RegExp(/\$\{(\w+?)\}/g),
text = "This is a string with ${var1} and ${var2} and {var3}",
result,
out = [];
while(result = regex.exec(text)) {
out.push(result[1]);
}
console.log(out);
This regex - \${([^\s}]+)(?=}) - should work.
Explanation:
\${ - Match literal ${
([^\s}]+) - A capture group that will match 1 or more character that are not whitespace or literal }.
(?=}) - A positive look-ahead that will check if we finally matched a literal }.
Here is sample code:
var re = /\${([^\s}]+)(?=})/g;
var str = 'This is a string with ${var1} and ${var2} and {var3}';
var arr = [];
while ((m = re.exec(str)) !== null) {
arr.push(m[1]);
}
alert(arr);
var str = 'This is a string with ${var1} and ${var2}';
var re = /\$\{(\w+?)\}/g;
var arr = [];
var match;
while (match = re.exec(str)) {
arr.push(match[1]);
}
console.log(arr);

Regex to get words between ":" and "," in javascript

I'm learning regex. I'm trying to get the most correct regex for the following :
Input is:
class:first,class:second,subject:math,subject:bio,room:nine
Expected output:
first,second,math,bio,nine
Want to store the above output in a string . var s = "";
Here's what I tried:
(:)(.*)(,)
However I want the last word too.
Using RegExp.prototype.exec:
var re = /:(.*?)(?:,|$)/g; // `,|$` : match `,` or end of the string.
var str = 'class:first,class:second,subject:math,subject:bio,room:nine';
var result = [];
var match;
while ((match = re.exec(str)) !== null)
result.push(match[1]);
result.join(',') // => 'first,second,math,bio,nine'
Using String.prototype.match, Array.prototype.map:
var re = /:(.*?)(,|$)/g;
var str = 'class:first,class:second,subject:math,subject:bio,room:nine';
str.match(re).map(function(m) { return m.replace(/[:,]/g, ''); }).join(',')
// => 'first,second,math,bio,nine'
Here is another method (based on the request so far):
var str = 'class:first,class:second,subject:math,subject:bio,room:nine';
// global match doesn't have sub-patterns
// there isn't a look behind in JavaScript
var s = str.match(/:([^,]+)(?=,|$)/g);
// result: [":first", ":second", ":math", ":bio", ":nine"]
// convert to string and remove the :
s = s.join(',').replace(/:/g, '');
// result: first,second,math,bio,nine"
Here is the fiddle

JavaScript regex using a character twice

So I'm using regex to grab information from a string, the issue is I need to both start up and stop at a / in the string.
Here's an example
var regexp = /\/(.*?)=(.*?)\//g;
var url_hash = "/s=lorem+ipsum/p=2/";
var match;
var result = {};
while ((match = regexp.exec(url_hash)) != null) {
result[match[1]] = match[2];
}
I can grab result['s'] without issue, but grabbing result['p'] becomes problematic, because the ending / for result['s'] is the same as the starting / for result['p']. If I changed the string to /s=lorem+ipsum//p=2/ it works perfectly, but of course that's hideous. So how can I fix this so that it both ends and starts up at the /? I'm stuck, any help is appreciated.
Use this regex:
/\/([^/=]+)=([^/]+)/
Code:
var regexp = /\/([^/=]+)=([^/]+)/g;
var url_hash = "/#!/s=lorem+ipsum/p=2/";
var match;
var result = {};
while ((match = regexp.exec(url_hash)) != null) {
result[match[1]] = match[2];
document.writeln(match[1] + ' = ' + match[2] + '<br>');
}
OUTPUT:
s = lorem+ipsum
p = 2
Online demo of the code
Why can't you just split it?
var result = {};
var url = "/#!/s=lorem+ipsum/p=2/".slice(4, -1).split('/');
for (i in url) {
var value = url[i].split('=');
result[value[0]] = value[1];
}
console.log(result);
You can determine the look-ahead set for part after the = yourself instead of adding it to the regular expression. The look-ahead set is "everything but a forward slash".
var regexp = /\/(\w+)=([^/]+)/g;
Btw, I'm assuming that the part before the = is word-like (i.e. alphanumeric)

Categories

Resources