Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript regex multiple captures again

Ok, I think I need to repost my question that was originally:

Javascript Regex group multiple

with a full example. I have:

        var text = ""+ 
            "<html>                           " +
            "  <head>                         " +
            "  </head>                        " +
            "  <body>                         " +
            "    <g:alert content='alert'/>   " +
            "    <g:alert content='poop'/>    " +
            "  </body>                        " +
            "</html>";

        var regex = /<([a-zA-Z]*?):([a-zA-Z]*?)\s([\s\S]*?)>/m;
        var match = regex.exec( text );
        console.log(match)

Output from console.log is:

Output from console.log

The problem is that I am only getting the result for the first ... not the other... what can I do to be able to capture and walk over all stuff that matched?

like image 287
mjs Avatar asked Feb 05 '13 12:02

mjs


People also ask

How do you repeat a capturing group in regex?

"Capturing a repeated group captures all iterations." In your regex101 try to replace your regex with (\w+),? and it will give you the same result. The key here is the g flag which repeats your pattern to match into multiple groups.

What is match and group in regex?

Regular expressions allow us to not just match text but also to extract information for further processing. This is done by defining groups of characters and capturing them using the special parentheses ( and ) metacharacters. Any subpattern inside a pair of parentheses will be captured as a group.

What is non capturing group in regex?

tl;dr non-capturing groups, as the name suggests are the parts of the regex that you do not want to be included in the match and ?: is a way to define a group as being non-capturing. Let's say you have an email address [email protected] . The following regex will create two groups, the id part and @example.com part.


1 Answers

exec returns only ONE result at a time and sets the pointer to the end of that match. Therefore, if you want to get ALL matches use a while loop:

while ((match = regex.exec( text )) != null)
{
    console.log(match);
}

To get all matches at one shot, use text.match(regex), in which the regex has g (global flag) specified. The g flag will make match find all matches to the regex in the string and return all the matches in an array.

[edit] and that's why my example HAD a g flag set! [/eoe]

var text = ""+ 
           "<html>                           " +
           "  <head>                         " +
           "  </head>                        " +
           "  <body>                         " +
           "    <g:alert content='alert'/>   " +
           "    <g:alert content='poop'/>    " +
           "  </body>                        " +
           "</html>";

// Note the g flag
var regex = /<([a-zA-Z]*?):([a-zA-Z]*?)\s([\s\S]*?)>/gm;

var match = text.match( regex );
console.log(match);

SIMPLE TEST:

<button onclick="myFunction()">Try it</button>

<script>
function myFunction()
{
var text = ""+ 
           "<html>                           " +
           "  <head>                         " +
           "  </head>                        " +
           "  <body>                         " +
           "    <g:alert content='alert'/>   " +
           "    <g:alert content='poop'/>    " +
           "  </body>                        " +
           "</html>";

// Note the g flag
var regex = /<([a-zA-Z]*?):([a-zA-Z]*?)\s([\s\S]*?)>/gi;

var n = text.match( regex );
alert(n);
}
</script>

working perfectly...

like image 175
itsid Avatar answered Oct 08 '22 05:10

itsid