如果指定了多个分隔符,javascript的split函数如何通过分隔符工作

时间:2019-01-12 00:26:53

标签: javascript regex split

我正在使用带有多个定界符的JavaScript的split函数来拆分字符串。尽管我可以使用它,但是它的行为使我感到困惑。寻找对此行为的解释

我在下面有这个字符串-

let z = 'c4 <= v4';

我用console.log(z.split(/(<|=|<=)/))分割了它。该字符串可能包含<=<=,这就是为什么我要用3个分隔符来分割它的原因。 这给了我[ 'c4 ', '<', '', '=', ' v4' ],这不是我期望的。我期待[ 'c4 ', '<=', ' v4' ]

然后我认为split正在分隔符列表中,因此它首先被<分开,然后被=分开,这将解释<和=之间的空元素。然后,当到达定界符<=时,在结果中找不到任何内容。

因此,为了证明我的想法,我尝试了console.log(z.split(/(=|<=)/))。 按照我的逻辑,我期望结果为[ 'c4 <', '=', ' v4' ],因为我期望split首先使用=作为定界符。 但是,实际结果是[ 'c4 ', '<=', ' v4' ]。几乎好像split跳过了定界符=

如果我安排定界符console.log(z.split(/(<=|<|=)/))的顺序,我将使其正常工作,并且将得到[ 'c4 ', '<=', ' v4' ],这加强了我的思想,因为<=是第一个指定的分隔符。

我搜索了一整堆,找不到这种行为的解释。分隔符如何分割工作?

非常感谢

2 个答案:

答案 0 :(得分:2)

在大多数正则表达式引擎中,当您​​有多个可以匹配同一字符串的替代项时,它将使用第一个匹配的字符串。因此,无论您写的是<|<=还是<=|<

如果输入字符串为foo<=bar,则第一个版本将仅匹配<,因为它是第一个匹配的替代,而第二个版本将匹配<=

这在Regular-Expression.info中有更详细的解释。

因此,通常的解决方案是按长度递减的顺序(例如,使用z.split(/(<=|<|=)/)

有些正则表达式引擎总是尝试找到最长的匹配项,而不是第一个匹配项(上面的页面称它们为“文本定向”)。但是JavaScript不会这样做。

答案 1 :(得分:1)

此处的替代顺序很重要。如果您在/(<|=|<=)/上进行拆分,则它将在第一个匹配项上拆分,即找到<。这意味着剩余的字符串不再具有该<=,而仅具有=,因此在该字符串上再次拆分。如果更改顺序,则可以确保<=<之前分别匹配=

let z = 'c4 <= v4';
console.log(z.split(/(<=|=|<)/))

/(=|<=)/的情况更加有趣,因为它与<=相匹配。

let z = 'c4 <= v4';
console.log(z.split(/(=|<=)/))

之所以这样,是因为正则表达式引擎渴望匹配。扫描字符串时,它看到的第一个潜在匹配是<。此时,它知道它与<=替代项有潜在的匹配,因此如果继续到下一个字符以查看它是否实际上是匹配项。事实证明如此,它继续前进并考虑了比赛。不需要单独测试=

如果您使用类似以下的内容,则可以避免所有这些情况:/([<=]+)/但这将更加宽容并匹配<=的任意组合

let z = 'c4 <= v4 == x4 =< z6 = a9 < b9';
console.log(z.split(/([<=]+)/g))