将字符串拆分为数组而不删除分隔符?

IT技术 javascript jquery
2021-02-16 20:57:44

我有一个像

 "asdf a  b c2 "

我想把它分成这样的数组:

["asdf", " ", "a", " ", " ", "b", " ", "c2", " "]

使用string.split(" ")删除空格,结果如下:

["asdf", "a", "", "b", "c2"]

我想插入额外的分隔符,例如

string.replace(/ /g, "| |").replace(/||/g, "|").split("|");

但这给出了意想不到的结果。

5个回答

相反分裂的,它可能会以为它是提取字符串包含任何分隔符或连续字符是容易没有分隔符:

'asdf a  b c2 '.match(/\S+|\s/g)
// result: ["asdf", " ", "a", " ", " ", "b", " ", "c2", " "]
'asdf a  b. . c2% * '.match(/\S+|\s/g)
// result: ["asdf", " ", "a", " ", " ", "b.", " ", ".", " ", "c2%", " ", "*", " "]

更莎士比亚式的比赛定义是:

'asdf a  b c2 '.match(/ |[^ ]+/g)

或(不到)+。

@gandalf3\S\s..相反,它也可以写成[^\s].
2021-04-30 20:57:44
@Jack 我没有,但这似乎有效!显然,我需要学习正则表达式.. \S+ 是什么意思?
2021-05-03 20:57:44
+1 但请注意:(?: )没有必要将其包装在非捕获组 ( ) 中。'asdf a b c2 '.match(/\S+|\s/g)会一样
2021-05-09 20:57:44

使用正向前瞻:

"asdf a  b c2 ".split(/(?= )/)
// => ["asdf", " a", " ", " b", " c2", " "]

编辑后编辑:正如我在评论中所说,缺乏后视使这有点棘手。如果所有单词都只由字母组成,您可以使用\b单词边界匹配器伪造lookbehind

"asdf a  b c2 ".split(/(?= )|\b/)
// => ["asdf", " ", "a", " ", " ", "b", " ", "c2", " "]

但是一旦你输入一些标点符号,它就会崩溃,因为它不仅在空格上中断:

"asdf-eif.b".split(/(?= )|\b/)
// => ["asdf", "-", "eif", ".", "b"]

如果您确实有不想中断的非字母,那么我还将建议一种后处理方法。

思考后编辑:这是基于 JamesA 的原始想法,但经过改进以不使用 jQuery,并正确拆分:

function chop(str) {
  var result = [];
  var pastFirst = false;
  str.split(' ').forEach(function(x) {
    if (pastFirst) result.push(' ');
    if (x.length) result.push(x);
    pastFirst = true;
  });
  return result;
}
chop("asdf a  b c2 ")
// => ["asdf", " ", "a", " ", " ", "b", " ", "c2", " "]
谢谢!这很好用,但接受了杰克的答案,因为它更短(尽管该解决方案确实在任何空白字符上拆分,而不仅仅是空格。但对我的情况来说很好)。如果可以的话,我会接受两者......(顺便说一句+1)
2021-04-29 20:57:44
这对于我在问题中所写的内容非常有用,但我刚刚意识到我在示例中犯了一个错误......请参阅我编辑过的问题。
2021-04-30 20:57:44
@limelights:最初拆分是在每个空间之前;现在是在每个空间之前和之后。不幸的是,JavaScript 没有lookbehind,所以这有点难……
2021-05-05 20:57:44
@gandalf3 你不希望它们作为字符串吗?
2021-05-10 20:57:44
@limelights 我希望每个空间都在一个元素中。一个元素中永远不应该有空格 + 其他任何东西。
2021-05-12 20:57:44

我很惊讶还没有人提到这一点,但为了完整起见,我将在这里发布。如果表达式中有捕获组,则将.split捕获的子字符串作为单独的条目包含在结果数组中:

"asdf a  b c2 ".split(/( )/)  // or /(\s)/
// ["asdf", " ", "a", " ", "", " ", "b", " ", "c2", " ", ""]

请注意,这与您指定的所需输出完全相同,因为它在两个连续空格之间和最后一个空格之后包含一个空字符串。

如有必要,您可以像这样从结果数组中过滤掉所有空字符串:

"asdf a  b c2 ".split(/( )/).filter(String)
// ["asdf", " ", "a", " ", " ", "b", " ", "c2", " "]

但是,如果这是您正在寻找的内容,我可能会建议您使用@Jack的解决方案

oop,对不起.. 最后的空字符串是错字。我已经编辑了我的问题。
2021-04-20 20:57:44
@gandalf3 好的,我已经提供了一个替代解决方案,可以在这种情况下为您提供所需的结果。
2021-05-03 20:57:44

你可以使用一点 jQuery

var toSplit = "asdf a  b c2 ".split(" ");
$.each(toSplit, 
    function(index, value) { 
        if (toSplit[index] == '') { toSplit[index] = ' '} 
    }
);

这将创建您正在寻找的输出,而其他元素上没有前导空格。

在较新的环境中不需要 jQuery -jQuery.each是一个穷人的[].foreach.
2021-04-22 20:57:44

尝试clean-split

const cleanSplit = require("clean-split");

cleanSplit("a-b-c", "-");
//=> ["a", "-", "b", "-", "c"]

cleanSplit("a-b-c", "-", { anchor: "before" });
//=> ["a-", "b-", "c"]

cleanSplit("a-b-c", "-", { anchor: "after" });
//=> ["a", "-b", "-c"]

在引擎盖下,它使用的逻辑改编自:

在您的情况下,您可以执行以下操作:

const cleanSplit = require("clean-split");

cleanSplit("asdf a  b c2 ", " ");
//=> ["asdf", " ", "a", " ", " ", "b", " ", "c2", " "]