[英]Why does string.split with a regular expression that contains a capturing group return an array that ends with an empty string?
[英]JavaScript: avoiding empty strings with String.split, and regular expression precedence
我正在创建一个语法高亮显示器,我使用String.split从输入字符串创建令牌。 第一个问题是String.split创建了大量的空字符串,这导致一切都比它原本要慢得多。
例如, "***".split(/(\\*)/)
- > ["", "*", "", "*", "", "*", ""]
。 有办法避免这种情况吗?
另一个问题是正则表达式本身的表达式优先级。 假设我正在尝试解析C风格的多行注释。 也就是/* comment */
。 现在让我们假设输入字符串是"/****/"
。 如果我使用下面的正则表达式,它会起作用,但产生许多额外的标记(以及所有那些空字符串!)。
/(\/\*|\*\/|\*)/
更好的方法是读取/*
, */
,然后在一个标记中读取所有其余的*
。 也就是说,上述字符串的更好结果是["/*", "**", "*/"]
。 但是,当使用应该执行此操作的正则表达式时,我会得到错误的结果。 正则表达式如下: /(\\/\\*|\\*\\/|\\*+)/
。
然而,这个表达式的结果是: ["/*", "***", "/"]
。 我猜这是因为最后一部分是贪婪的,所以它从其他部分窃取了比赛。
我找到的唯一解决方案是制作一个否定的前瞻表达式,如下所示:
/(\/\*|\*\/|\*+(?!\/)/
这给出了预期的结果,但与其他结果相比它非常慢,这对大字符串有影响。
是否有解决这些问题的方法?
使用lookahed来避免空匹配:
arr = "***".split(/(?=\*)/);
//=> ["*", "*", "*"]
或使用filter(Boolean)
来丢弃空匹配:
arr = "***".split(/(\*)/).filter(Boolean);
//=> ["*", "*", "*"]
通常用于标记化您使用match
,而不是split
:
> str = "/****/"
"/****/"
> str.match(/(\/\*)(.*?)(\*\/)/)
["/****/", "/*", "**", "*/"]
还要注意非贪心修饰符?
解决了第二个问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.