I'm trying to match from the following string:
[[NOTE]]This is my note.[[NOTE]]
the following pattern:
This is my note.
As I can't use lookaheads, this is my current attempt:
[^\[\[NOTE\]\]](.*)[^\[\[NOTE\]\]]
But it still doesn't work.
I'm trying to match from the following string:
[[NOTE]]This is my note.[[NOTE]]
the following pattern:
This is my note.
As I can't use lookaheads, this is my current attempt:
[^\[\[NOTE\]\]](.*)[^\[\[NOTE\]\]]
But it still doesn't work.
Your current regex wouldn't work. Some points:
You're putting everything inside a character class: [^...]
. It makes it so the regex matches a character from the list, which is not what you want in this case. Remove them.
If I understand your question correctly, you don't actually need lookaround expressions for what you're trying to do. And JavaScript does support lookaheads; it doesn't support lookbehinds though.
Assuming you're trying to match the text between the opening and closing [[NOTE]]
tags, why not just use:
\[\[NOTE\]\]([^\[\]]+)\[\[NOTE\]\]
Explanation:
\[\[NOTE\]\]
matches [[NOTE]]
[^\[\]]+
is a negated character class that matches one or more characters that is not a [
or ]
.
Use what you captured in the first capturing group:
var re = /\[\[NOTE]](.*?)\[\[NOTE]]/;
var str = '[[NOTE]]This is my note.[[NOTE]]';
var m = re.exec(str);
console.log(m[1])
// This is my note.
Making your *
quantifier lazy by adding a ?
avoid matching This a note[[NOTE]][[NOTE]]Also note
in
[[NOTE]]This a note[[NOTE]][[NOTE]]Also note[[NOTE]]
You need to escape the opening [
bracket in your regex and also you have to remove the ^
symbol from the character class.
\[\[NOTE]]((?:(?!\[\[NOTE]]).)*)\[\[NOTE]]
> var re = /\[\[NOTE]]((?:(?!\[\[NOTE]]).)*)\[\[NOTE]]/g;
undefined
> var str = '[[NOTE]]This is my note.[[NOTE]]';
undefined
> var m;
undefined
> while ((m = re.exec(str)) != null) {
... console.log(m[1]);
... }
This is my note.
First of all, lookahead is fully supported in javascript (lookbehind not).
In your regex [^\[\[NOTE\]\]](.*)[^\[\[NOTE\]\]]
[]
can check only the existence of single characters. For example the [^cat]
matches any characters which are not c
or a
or t
.*?
to match only the fist closing token if it is a long template.Without these mistakes it works perfectly: \[\[NOTE\]\](.*?)\[\[NOTE\]\]
[[NOTE]]This is my note.[[NOTE]]
and with the first capturing group the This is my note.
.Another option to capture the opening token and use the backreference by the closing token:
(\[\[NOTE\]\])(.*?)\1
Or you can use a positive lookahead
(\[{2,2}NOTE\]{2,2})(.*?)(?=\1)
[[NOTE]]This is my note.
.If you want to use a different closing tag, for example [[/NOTE]]
, then you can use something like these:
\[{2,2}(NOTE)\]{2,2}(.*?)(?=\[{2,2}\/\1\]{2,2})
\[{2,2}(NOTE)\]{2,2}(.*?)\[{2,2}\/\1\]{2,2}
If you want to use nested open-close statements, then the only option to parse the template token by token. By perl compatible regex there is something called recursive regex. With that it is much easier to parse nested open-close templates, but that feature is not available in javascript... If you don't want to support nested structures, then the actual regex will be enough. Use the first capturing group instead of the full match, that's all. Lookaround is not necessary...
Btw. I strongly recommend you to use an existing template system, we don't need another one... What Javascript Template Engines you recommend?