【发布时间】:2014-09-04 12:14:30
【问题描述】:
我正在尝试从以下字符串进行匹配:
[[NOTE]]This is my note.[[NOTE]]
以下模式:
This is my note.
由于我不能使用前瞻,这是我目前的尝试:
[^\[\[NOTE\]\]](.*)[^\[\[NOTE\]\]]
但还是不行。
【问题讨论】:
标签: javascript regex
我正在尝试从以下字符串进行匹配:
[[NOTE]]This is my note.[[NOTE]]
以下模式:
This is my note.
由于我不能使用前瞻,这是我目前的尝试:
[^\[\[NOTE\]\]](.*)[^\[\[NOTE\]\]]
但还是不行。
【问题讨论】:
标签: javascript regex
使用您在第一个捕获组中捕获的内容:
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.
通过添加 ? 避免匹配 This a note[[NOTE]][[NOTE]]Also note 使您的 * 量词变得懒惰
[[NOTE]]This a note[[NOTE]][[NOTE]]Also note[[NOTE]]
【讨论】:
您当前的正则表达式不起作用。几点:
您将所有内容都放在一个字符类中:[^...]。它使得正则表达式匹配列表中的一个字符,这 不是 在这种情况下你想要的。删除它们。
如果我正确理解了您的问题,您实际上并不需要环顾表达式来表达您正在尝试做的事情。 JavaScript确实支持前瞻;但它不支持lookbehinds。
假设您正在尝试匹配开始和结束 [[NOTE]] 标记之间的文本,为什么不直接使用:
\[\[NOTE\]\]([^\[\]]+)\[\[NOTE\]\]
解释:
\[\[NOTE\]\] 匹配 [[NOTE]]
[^\[\]]+ 是一个否定字符类,它匹配一个或多个不是[ 或] 的字符。
【讨论】:
您需要在您的正则表达式中转义左 [ 括号,还必须从字符类中删除 ^ 符号。
\[\[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.
【讨论】:
((?:(?!\[\[NOTE]]).)*) 来捕获中间的文本。这肯定比其他替代方案慢,主要是因为它需要检查每个位置并查看它后面是否没有[[NOTE]]。为什么不使用否定字符类呢?
\[\[NOTE\]\]([^\[\]]+)\[\[NOTE\]\],只是.*? 可以完成这项工作?
.*? 更具体。如果您查看您发布的演示链接上的正则表达式调试器,您会发现您的正则表达式仅在 95 步 后才能找到匹配项,而我的仅需要 21 步。
[,您的答案将不起作用。 [[NOTE]]This is my [note.[[NOTE]] OP 想要两个 [[NOTE]] 之间的文本
首先,javascript 中的前瞻是fully supported(后瞻不是)。
在你的正则表达式[^\[\[NOTE\]\]](.*)[^\[\[NOTE\]\]]
[] 只能检查单个字符的存在。例如,[^cat] 匹配任何不是c 或a 或t 的字符。*?,如果它是一个长模板,则只匹配第一个结束标记。没有这些错误,它可以完美运行:\[\[NOTE\]\](.*?)\[\[NOTE\]\]
[[NOTE]]This is my note.[[NOTE]] 匹配,并与第一个捕获组This is my note. 匹配。另一种捕获开始令牌并使用backreference 作为结束令牌的选项:
(\[\[NOTE\]\])(.*?)\1或者您可以使用positive lookahead
(\[{2,2}NOTE\]{2,2})(.*?)(?=\1)[[NOTE]]This is my note.。如果你想使用不同的结束标签,例如[[/NOTE]],那么你可以使用类似这样的东西:
\[{2,2}(NOTE)\]{2,2}(.*?)(?=\[{2,2}\/\1\]{2,2})\[{2,2}(NOTE)\]{2,2}(.*?)\[{2,2}\/\1\]{2,2}如果你想使用嵌套的开闭语句,那么唯一的选择就是逐个标记解析模板标记。通过 perl 兼容的正则表达式,有一个叫做 recursive regex 的东西。有了它,解析嵌套的开闭模板就容易多了,但该功能在 javascript 中不可用......如果您不想支持嵌套结构,那么实际的正则表达式就足够了。使用第一个捕获组而不是完整匹配,仅此而已。 Lookaround 没必要……
顺便说一句。我强烈建议您使用现有的模板系统,我们不需要另一个...What Javascript Template Engines you recommend?
【讨论】: