Can anyone help converting this PHP regex pattern to a JavaScript compatible one?
PHP
preg_match_all('/(?ims)([a-z0-9\s\.\:#_\-@,]+)\{([^\}]*)\}/', $data, $matches);
Javascript
matches=data.match(/(?ims)([a-z0-9\s\.\:#_\-@,]+)\{([^\}]*)\}/);
Thanks
To mimic the PHP output, you need to look at more than only the regular expression. For a single match, the JavaScript match method will do the trick, but for multiple matches it will no longer return the captured groups. In fact, there is no out-of-the-box statement in JavaScript that is equivalent to preg_match_all.
The method that comes closest is regex.exec, being the only method that can both return the captured groups and multiple matches. But it does not return all the matches in one go. Instead you need to iterate over them, for instance like this:
for (matches = []; result = regex.exec(data); matches.push(result));
Now the regular expression needs also some adjustments:
In Javascript the modifiers (ims) cannot be specified like you have it, they must be specified at the end, after the closing slash. Note that in PHP you can do the same.
Secondly, Javascript has no support for the s modifier. But in your case this is not a problem, as your regular expression does not rely on it -- you would get the same results without that modifier.
In order for the exec method to return multiple matches, the regular expression must use the g modifier, which is not needed nor allowed in PHP's preg_match_all -- the _all in the method name already takes care of that.
So, in JavaScript, the regular expression will be defined like this:
var regex = /([a-z0-9\s\.\:#_\-@,]+)\{([^\}]*)\}/gim;
Finally, the matches are returned in a different format than in PHP. Let's say the data is "Alpha{78} Beta{333}", then PHP will return:
[["Alpha{78}"," Beta{333}"],["Alpha"," Beta"],["78","333"]]
But the above JavaScript code returns that data in a transposed way (rows and columns are swapped):
[["Alpha{78}","Alpha","78"],[" Beta{333}"," Beta","333"]]
So, if you also want that to be the same, you need to transpose that array. Here is a generic transpose function you could use for that:
function transpose(a) {
return a[0].map(function (val, c) {
return a.map(function (r) {
return r[c];
});
});
}
So putting it all together, this will do the job:
function transpose(a) {
return a[0].map(function (val, c) {
return a.map(function (r) {
return r[c];
});
});
}
// test data:
var data = "Alpha{78} Beta{333}";
var regex = /([a-z0-9\s\.\:#_\-@,]+)\{([^\}]*)\}/gim;
// collect all matches in array
for (var matches = []; result = regex.exec(data); matches.push(result));
// reorganise the array to mimic PHP output:
matches = transpose(matches);
console.log(JSON.stringify(matches));
// for this snippet only:
document.write(JSON.stringify(matches));
Output:
[["Alpha{78}"," Beta{333}"],["Alpha"," Beta"],["78","333"]]
</div>