1

So I'm just curious if there was a way to chain regexp. Just looking to optimize my code a little. I want to find an expression, then find another one from the results.

The Working Code:

match = $('body').html().match(/(\[~\{ .*? \}~\])/g);
console.log(match[0]);

findText = match[0].match(/\w+/);
console.log(findText);

What I've tried:

match = $('body').html().match(/(\[~\{ .*? \}~\])(\w+)/g);
console.log(match[0]);

produced an error

match = $('body').html().match(/(\[~\{ .*? \}~\])|(\w+)/g);
console.log(match[0]);

Found Expression 1 and then Found Expression 2 outside of expression 1.

My HTML:

[~{ header }~]

<p>This is the home page</p>

[~{ footer }~]
jemiloii
  • 24,594
  • 7
  • 54
  • 83
  • You want to write one regexp which actually selects what you are looking for, not chain together two partials. `.match()` is a javascript string function, not a jquery function so ti returns an array of results (or null if nothign matches) which makes chaining (with error control) difficult. What are you actually trying to acheive here? – Adam Apr 18 '14 at 22:40
  • In the body find [~{ anything }~], then extract anything out of what it found. – jemiloii Apr 18 '14 at 22:44
  • The working code section does exactly what I want it to do, just seeing if i could optimize it. – jemiloii Apr 18 '14 at 22:45

1 Answers1

2

I just used a capturing group for the word inside the [~{ ... }~] structure.

\[~\{ (\w+) \}~\]

The only difference is I matched (\w+) instead of .*?. I also removed the capture group ((...)) that was around the whole expression, since it wasn't necessary.

Regex101


Now it is a little difficult to access multiple capture groups in Javascript, but I used some example code from this answer (thanks Mathias Bynens):

function getMatches(string, regex) {
    var matches = [];
    var match;
    while (match = regex.exec(string)) {
        matches.push(match);
    }
    return matches;
}

var myString = $('body').html();
var myRegEx = /\[~\{ (\w+) \}~\]/g;

var matches = getMatches(myString, myRegEx);
console.log(matches[0]);

Output:

Array[2]
  0: "[~{ header }~]"    // The whole match
  1: "header"            // The captured group

JSFiddle


So your final code could look something like this (this is pseudo-code):

matches; // this is set from previous code block

for(var i = 0; i < matches.length; i++) {
    var needsToBeReplaced = matches[i][0];
    var template = getTemplate(matches[i][1]);
}
Community
  • 1
  • 1
Sam
  • 20,096
  • 2
  • 45
  • 71
  • Thanks for the reply, however this just returns [~{ header }~] vs just returing header – jemiloii Apr 18 '14 at 22:58
  • @JemiloII see my final update. It will be an array of matches. Each match will be an array containing the entire match (`[~{ header }~]`) at the 0-index and the captured group (`header`) at the 1-index. – Sam Apr 18 '14 at 22:59
  • 1
    wow, this works really nice this way! I like the multi-demensional array format. This format will make it easier for replacing the code later with updated content easier. For jsfiddle, if you add https://getfirebug.com/firebug-lite-debug.js as an external resource, you get a debugger. http://jsfiddle.net/cqTAv/1/ – jemiloii Apr 18 '14 at 23:10
  • @JemiloII dang I wish I could hug you for that JSFiddle tip, super handy for personal and SO use! – Sam Apr 18 '14 at 23:11