我正在创建语法高亮显示,我使用String.split从输入字符串创建标记。 第一个问题是String.split创建了大量的空字符串,这导致一切都比它原本要慢得多。
例如,"***".split(/(\*)/)
- > ["", "*", "", "*", "", "*", ""]
。
有没有办法避免这种情况?
另一个问题是正则表达式本身的表达式优先级。
假设我正在尝试解析C风格的多行注释。
也就是/* comment */
。
现在让我们假设输入字符串是"/****/"
。
如果我使用下面的正则表达式,它会起作用,但会产生很多额外的标记(以及所有那些空字符串!)。
/(\/\*|\*\/|\*)/
更好的方法是阅读/*
,*/
,然后在一个标记中阅读*
的所有其余部分。
也就是说,上述字符串的更好结果是["/*", "**", "*/"]
。
但是,当使用应该执行此操作的正则表达式时,我会得到错误的结果。
正则表达式如下:/(\/\*|\*\/|\*+)/
。
此表达式的结果是:["/*", "***", "/"]
。
我猜这是因为最后一部分是贪婪的,所以它从其他部分窃取了比赛。
我找到的唯一解决方案就是制作一个否定的前瞻表达式,如下所示:
/(\/\*|\*\/|\*+(?!\/)/
这给出了预期的结果,但与其他结果相比它非常慢,这对大字符串有影响。
是否有解决这些问题的方法?
答案 0 :(得分:17)
使用lookahed来避免空匹配:
arr = "***".split(/(?=\*)/);
//=> ["*", "*", "*"]
或使用filter(Boolean)
丢弃空匹配:
arr = "***".split(/(\*)/).filter(Boolean);
//=> ["*", "*", "*"]
答案 1 :(得分:1)
通常,为了进行标记,您使用的是match
,而不是split
:
> str = "/****/"
"/****/"
> str.match(/(\/\*)(.*?)(\*\/)/)
["/****/", "/*", "**", "*/"]
另请注意非贪婪修饰符?
如何解决第二个问题。