问题 使用split将字符串拆分为2个字符的组?


我有这个简单的字符串:

"a1a2a3"

是否有可以使用的正则表达式 split 命令所以它会将字符串拆分成一对? :

["a1","a2","a3"]  ?

我试过这个:

"a1a2a3".split(/(?=..)/)

但它回来了 ["a", "1", "a", "2", "a3"]

附:

我可以做到 Match 但我正在寻找(如果存在)正则表达式,它可以帮助我使用 split 


10141
2017-08-23 16:05


起源

想要使用一种旨在删除字符的方法来保留字符的动机是什么?
这有多高? A1-A100 ...超越? a1-9,b1-9等? - smerny
几个月前,我想我已经看到了分裂的答案,但我找不到它。 - Denys Séguret
@dystroy你在说什么 这个? ,如果你这样做,它不适用于“a1a2a3” - Royi Namir
有没有理由不能使用 match?这更像是一个学术问题吗? - talemyn


答案:


split 对于偶数长度字符串:

str.split(/(?=(?:..)*$)/)

split 对于奇数长度字符串,最后一个条目具有单个字符:

str.split(/(?=(?:..)*.$)/)

这些基本上是前瞻,检查前面的字符数是奇数还是偶数。它利用了以下事实:在所有分割位置前面的字符数具有与字符串长度相同的奇偶校验。

(偶数版)前瞻的模式是 (?:..)*$,检查偶数个字符 (?:..)* 在字符串结束之前 $。 (注意非捕获组 (?:pattern) 在这里使用,否则,捕获组将在中创建额外的条目 split 结果)。类似的解释适用于奇数版本。

注意 .  排除了几个新的行字符\n\r\u2028 要么 \u2029。它会对包含这些字符的字符串产生意外的结果。更换 . 同 [\s\S] (或其他等效构造)使其适用于所有情况。


出于实用目的, match 是这项工作的正确工具:

str.match(/..?/g)

例如:

"1234567890".match(/..?/g)
> [ "12", "34", "56", "78", "90" ]

"1234567890".match(/..?/g)
> [ "12", "34", "56", "78", "9" ]

该解决方案可以扩展为n个字符组:

str.match(/.{1,<n>}/g)

例如:

"123456789012345678901234567890".match(/.{1,7}/g)
> [ "1234567", "8901234", "5678901", "2345678", "90" ]

它只是利用了贪婪的量词并创建了n个字符组,然后用完了最后一组的字符。

与上面相同,您可能想要更改 . 至 [\s\S] 使其适用于所有情况。


10
2017-08-24 14:53



终于。这可以将一元条件缩短为1表达式......str.length%2==0? /../:/../ - Royi Namir
+1这非常漂亮 - Denys Séguret


我已经在聊天中回答了这个问题你真的应该使用 String.prototype.match

可以用拆分完成吗?从技术上讲,是的。你可以拆分它 /(..)/ 然后过滤掉空白字符串。

"a1a2a3".split(/(..)/).filter(function(a){
    return a !== '';
});

4
2017-08-23 16:09



要么 "a1a2a3".split(/(..)/).filter(Boolean)
@CrazyTrain很好!让我们切掉一个字节并改用String。 "a1a2a3".split(/(..)/).filter(String) - nderscore
@CrazyTrain ......为什么这个有用? - Aakil Fernandes
@AakilFernandes Boolean function会将每个字符串强制转换为布尔值true / false。由于空字符串是假值,因此将在结果数组中过滤掉这些值。 - nderscore


我不确定输入字符串的所有可能格式是什么,但我认为它是一些字母后跟一些数字。

如果是这样,你可以尝试:

var str = 'abc123d56efg8t5'
var res = str.split(/([a-z]+[0-9]+)/).filter(Boolean);

输出:

["abc123", "d56", "efg8", "t5"]

2
2017-08-23 16:38