Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3311004
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 17, 20262026-05-17T21:49:32+00:00 2026-05-17T21:49:32+00:00

Have a regex: .*? (rule1|rule2) (?:(rule1|rule2)|[^}])* (It’s designed to parse CSS files, and the

  • 0

Have a regex:

.*?
(rule1|rule2)
(?:(rule1|rule2)|[^}])*

(It’s designed to parse CSS files, and the ‘rules’ are generated by JS.)

When I try this in IE, all works as it should.
Ditto when I try it in RegexBuddy or The Regex Coach.

But when I try it in Firefox or Chrome, the results are missing values.
Can anyone please explain what the real browsers are thinking, or how I can achieve results similar to IE’s?

To see this in action, load up a page that gives you interactive testing, such as the W3Schools try-it-out editor.

Here’s the source that can be pasted in:
http://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_regexp_exec

<html>
<body>

<script type="text/javascript">

var str="#rot { rule1; rule2; }";

var patt=/.*?(rule1|rule2)(?:(rule1|rule2)|[^}])*/i;

var result=patt.exec(str);
for(var i = 0; i < 3; i++) document.write(i+": " + result[i]+"<br>"); 

</script>
</body>
</html>

Here is the output in IE:

0: #rot { rule1; rule2; 
1: rule1
2: rule2

Here is the output in Firefox and Chrome:

0: #rot { rule1; rule2; 
1: rule1
2: undefined

When I try the same using string.match, I get back an array of undefined in all browsers, including IE.

var str="#rot { rule2; rule1; rule2; }";
var patt=/.*?(rule1|rule2)(?:(rule1|rule2)|[^}])*/gi;
var result=str.match(patt);
for(var i = 0; i < 5; i++) document.write(i+": "+result[i]+"<br>"); 

As far as I can tell, the issue is the last non-capturing parenthesis.
When I remove them, the results are consistent cross browser – and match() gets results.

However, it does capture from the last parenthesis, in all browsers, in the following example:

<script>
var str="#rot { rule1; rule2 }";
var patt=/.*?(rule1|rule2)(?:(rule1 |rule2 )|[^}])*/gi;
var result=patt.exec(str);
for(var i =0; i < 3; i++) document.write(i+": "+result[i]+"<br>"); 
</script>

Notice that I’ve added a space to the patterns in the second regex.
The same applies if I add any negative character to the strings in the second regex:

var patt=/.*?(rule1|rule2)(?:(rule1[^1]|rule2[^1])|[^}])*/gi;

What the expletive is going on?!
All other strings that I’ve tried result in the first set of non-catches.
Any help is greatly appreciated!

EDIT:
The code has been shortened, and many hours of research put in, on Mathhew’s advice.
The title has been changed to make the thread easier to find.

I have marked Mathew’s answer as correct, as it is well researched and described.
My answer below (written before Mathew revised his) states the logic in simpler and more direct terms.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-17T21:49:33+00:00Added an answer on May 17, 2026 at 9:49 pm

    IE is wrong. In ECMAScript, exactly one alternative can result in a string. All the others have to be undefined (not "" or anything else).

    So for your alternatives, including (transform[^-][^;}]+)|(transform-origin[^;}]+), Firefox and Chrome are correct in setting the failed capture to undefined.

    There’s an example in the ECMAScript 5 standard (§15.10.2.3) specifically about this:

    NOTE The | regular expression operator
    separates two alternatives. The
    pattern first tries to match the left
    Alternative (followed by the sequel of
    the regular expression); if it fails,
    it tries to match the right
    Disjunction (followed by the sequel of
    the regular expression). If the left
    Alternative, the right Disjunction,
    and the sequel all have choice points,
    all choices in the sequel are tried
    before moving on to the next choice in
    the left Alternative. If choices in
    the left Alternative are exhausted,
    the right Disjunction is tried instead
    of the left Alternative. Any capturing
    parentheses inside a portion of the
    pattern skipped by | produce undefined
    values instead of Strings.

    Thus, for
    example, /a|ab/.exec(“abc”) returns
    the result “a” and not “ab”. Moreover,
    /((a)|(ab))((c)|(bc))/.exec(“abc”)
    returns the array [“abc”, “a”, “a”,
    undefined, “bc”, undefined, “bc”] and
    not [“abc”, “ab”, undefined, “ab”,
    “c”, “c”, undefined]

    EDIT: I figured the last part out. This applies to the original as well as the simplified version. In both cases, rule1 and rule2 can’t match the ; (in the original because ; is in the negated character class [^;}]). Thus, when a ; hit between declarations, the alternation chooses [^}]. Thus, it must set the last two captures to undefined.

    For the * to be fully greedy, the final ; and space in the input must also be matched. For the last two * repetitions (‘;’ and ‘ ‘), the alternation again chooses [^}], so the captures should be set undefined at the end too.

    IE fails to do this in both cases, so they stay equal to “rule1” and “rule2”.

    Finally, the reason that the second example behaves differently is that (transform-origin[^;}]+)) matches on the very last * repetition, since there’s no ; before the end.

    EDIT 2: I’ll walk through what should be happening both current examples. match is the match array.

    var str="#rot { rule1; rule2; }";
    var patt=/.*?(rule1|rule2)(?:(rule1|rule2)|[^}])*/i;
    
    .*? - "#rot { "
    
    (rule1|rule2) - "rule1"
    match[1] = "rule1"
    

    Star 1

    [^}] - ";"
    match[2] = undefined 
    

    Star 2

    [^}] - " "
    match[2] = undefined 
    

    Star 3

    (rule1|rule2) - "rule2"
    match[2] = "rule2"
    

    Star 4

    [^}] - ";"
    match[2] = undefined 
    

    Star 5

    [^}] - " "
    match[2] = undefined 
    

    Again, IE isn’t setting match[2] to undefined.

    For the str.match example, you’re using the global flag. That means it returns an array of matches, without captures. This applies to any use of String.match. If you use g, you have to use exec to get captures.

    var str="#rot { rule1; rule2 }";
    var patt=/.*?(rule1|rule2)(?:(rule1 |rule2 )|[^}])*/gi;
    
    .*? - "#rot { "
    (rule1|rule2) - "rule1"
    match[1] = "rule1"
    

    Star 1

    [^}] - ";"
    match[2] = undefined 
    

    Star 2

    [^}] - " "
    match[2] = undefined 
    

    Star 3

    (rule1 |rule2 ) - "rule2 "
    match[2] = "rule2 "
    

    Since this is the last *, the capture never gets set to undefined.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

So I have this regex: (^(\s+)?(?P<NAME>(\w)(\d{7}))((01f\.foo)|(\.bar|\.goo\.moo\.roo))$|(^(\s+)?(?P<NAME2>R1_\d{6}_\d{6}_)((01f\.foo)|(\.bar|\.goo\.moo\.roo))$)) Now if I try and do a match
Ok so I have this regex that I created and it works fine in
I have this regex I built and tested in regex buddy. _ [ 0-9]{10}+
I have a regex that is going to end up being a bit long
I have a regex call that I need help with. I haven't posted my
I have a RegEx that is working for me but I don't know WHY
I have simple regex \.*\ for me its says select everything between and ,
I have a regex created from a list in a database to match names
Anyone have a regex to strip lat/long from a string? such as: ID: 39.825
A tutorial I have on Regex in python explains how to use the re

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.