1

I have a pretty simple regex expression,

"lang-bash".match("lang-([a-z]+)", "gi")

And on latest Chrome (43-ish) I get the expected behaviour of ["lang-bash", "bash"]. When I try to the same on the latest FireFox (39 or 41a) I get ["lang-bash"]. I also tried this in Safari (8.0.7) and it has the expected result of ["lang-bash", "bash"].

So this might be a bug in FireFox, which I can submit for, but I'm expecting it's just something I don't understand. Thanks!

Edit: Alright... so some more testing.

FireFox

"lang-bash lang-dash".match(/lang-([a-z]+)/i)
Array [ "lang-bash", "bash" ]
"lang-bash lang-dash".match(/lang-([a-z]+)/ig)
Array [ "lang-bash", "lang-dash" ]
"lang-bash lang-dash".match("lang-([a-z]+)", "gi")
Array [ "lang-bash", "lang-dash" ]

Safari

"lang-bash lang-dash".match(/lang-([a-z]+)/i)
[ "lang-bash", "bash" ]
"lang-bash lang-dash".match(/lang-([a-z]+)/ig)
[ "lang-bash", "lang-dash" ]
"lang-bash lang-dash".match("lang-([a-z]+)", "gi")
["lang-bash", "bash"]

Chrome

"lang-bash".match(/lang\-([a-z]+)/i)
["lang-bash", "bash"]
"lang-bash".match(/lang\-([a-z]+)/gi)
["lang-bash"]
"lang-bash lang-dash".match("lang-([a-z]+)", "gi")
["lang-bash", "bash"]

Since there's a capture, I'd expect the result of anything with the flags ig to be [ "lang-bash", "lang-dash", "bash", "dash" ] but I guess that's not correct at all. It seems all the browsers act differently here. Anyone have some idea what's going on?

Travis
  • 10,444
  • 2
  • 28
  • 48
  • This looks like an array of captures starting from group 0 to group 1. What were you expecting? In some languages, `match` is going to match the whole string, so the global `g` option is meaningless. Perhaps you are looking for search or find. –  Jul 13 '15 at 20:39
  • `g` shouldn't be meaningless because my input could have multiple values. Just the example I gave doesn't. Making a more meaningful input string makes me even more confused. I really just care about the captures. – Travis Jul 13 '15 at 23:28

2 Answers2

1

Originally, Firefox implements non-standard flags argument in String.prototype.{search, match, replace}. This argument will be deprecated in Firefox 39 and will be removed in future version. See more in the bug report about this issue.

What you see in Firefox is due to the effect of the flags argument.

When match is used with a global g pattern, only the main matches are included. Without the global flag, match returns the first match in index 0 and the captured text in indices from 1.

Since Firefox is aware of the flags argument, it returns all the main matches without the capturing groups, as seen in:

"lang-bash lang-dash".match("lang-([a-z]+)", "gi")
"lang-bash".match("lang-([a-z]+)", "gi")

Other browsers ignore the flags argument, so the result only shows the first match and the capturing groups.

If you need the flags, specify it in the RegExp literal (if the pattern is fixed) or the RegExp constructor (if the pattern is dynamic).

nhahtdh
  • 55,989
  • 15
  • 126
  • 162
0

Okay, it appears I'm just looking at how the different browsers deal with match or how they display the data when logged.

function getMatches(string, regex, index) {
  index || (index = 1); // default to the first capturing group
  var matches = [];
  var match;
  while (match = regex.exec(string)) {
    matches.push(match[index]);
  }
  return matches;
}
getMatches("lang-bash lang-dash", /lang\-([a-z]+)/ig)

Has the same value across Chrome, Safari, FireFox, and Node.js of [ 'bash', 'dash' ]. Thanks to How do you access the matched groups in a JavaScript regular expression? for the code that made me explore this option.

Community
  • 1
  • 1
Travis
  • 10,444
  • 2
  • 28
  • 48