1

I have following regex and template for underscore.js templates.

the problem is that the regex for interpolate is not working properly, what will be correct regex?

Regex

var settings = {
    evaluate: /\{\{\#([\s\S]+?)\}\}/g,
    interpolate: /\{\{[a-zA-Z](.+?)\}\}/g
};

Template

{{# if ( item ) { }}
    {{ item.title }}
{{# } }}
1
  • I'm not sure I understand all the terms, but your match in interpolate begins with an alphabet character, whereas {{ item.title }} begins with a whitespace. Maybe you could use /\{\{\s[a-zA-Z](.+?)\}\}/g? Note that this matches {{ item.title }} but captures tem.title. To capture .title, you will need to use /\{\{\s[a-zA-Z]+(.+?)\}\}/g Commented May 15, 2013 at 8:22

1 Answer 1

1

The template compiler will use the last capture group in the expressions to build the JavaScript form of the template. In your case, the interpolate will (as noted by Jerry) ignore the first alphabetic character so {{ab}} will end up looking for b in the template parameters. Your regex also doesn't account for leading whitespace. You'd want something more like this:

/\{\{\s*([a-zA-Z](?:.+?))\s*\}\}/g

or better, just leave out the original group instead of converting it to a non-capturing group:

/\{\{\s*([a-zA-Z].+?)\s*\}\}/g

Or even better, get right to the heart of the problem and say exactly what you mean:

/\{\{([^#].*?)\}\}/g

I think the problem that led you to your original regex is that interpolate is checked before evaluate; that order makes sense when interpolate is looking for <%= ... %> and evaluate is looking for <% ... %> (i.e. the default delimiters are being used). In your case, you need a bit of extra [^#] trickery to get around the regex checking order.

Similarly, we can simplify your evaluate regex:

/\{\{#(.+?)\}\}/g

Demo: http://jsfiddle.net/ambiguous/V6rv2/

I'd also recommend that you add an escape pattern for completeness.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks a lot, before your reply, I tried fixing regex myself and got /\{\{([^#][\s\S].+?)\}\}/g working ;) but now I replaced it with yours /\{\{([^#].*?)\}\}/g. and yes I am also using /\{\{\{(.+?)\}\}\}/g for escape.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.