我如何分裂一个字符串与多个分隔符在JavaScript?

我试图拆分逗号和空格,但AFAIK JavaScript的split()函数只支持一个分隔符。


当前回答

我在寻找c# string. split()函数的替代品时遇到了这个问题,该函数使用参数中的字符分割字符串。

在JavaScript中,你可以使用map和reduce来迭代分隔字符和中间值:

let splitters = [",", ":", ";"]; // or ",:;".split("");
let start= "a,b;c:d";
let values = splitters.reduce((old, c) => old.map(v => v.split(c)).flat(), [start]);
// values is ["a", "b", "c", "d"]

Flat()用于平滑中间结果,因此每次迭代都处理没有嵌套数组的字符串列表。每次迭代对old中的所有值应用split,然后返回拆分器中要被下一个值拆分的中间结果列表。Reduce()使用包含初始字符串值的数组进行初始化。

其他回答

从@stephen-sweriduk解决方案开始(这对我来说更有趣!),我对它进行了轻微的修改,使其更加通用和可重用:

/**
 * Adapted from: http://stackoverflow.com/questions/650022/how-do-i-split-a-string-with-multiple-separators-in-javascript
*/
var StringUtils = {

  /**
   * Flatten a list of strings
   * http://rosettacode.org/wiki/Flatten_a_list
   */
  flatten : function(arr) {
    var self=this;
    return arr.reduce(function(acc, val) {
        return acc.concat(val.constructor === Array ? self.flatten(val) : val);
    },[]);
  },

  /**
   * Recursively Traverse a list and apply a function to each item
   * @param list array
   * @param expression Expression to use in func
   * @param func function of (item,expression) to apply expression to item
   *
   */
  traverseListFunc : function(list, expression, index, func) {
    var self=this;
    if(list[index]) {
        if((list.constructor !== String) && (list[index].constructor === String))
            (list[index] != func(list[index], expression)) ? list[index] = func(list[index], expression) : null;
        (list[index].constructor === Array) ? self.traverseListFunc(list[index], expression, 0, func) : null;
        (list.constructor === Array) ? self.traverseListFunc(list, expression, index+1, func) : null;
    }
  },

  /**
   * Recursively map function to string
   * @param string
   * @param expression Expression to apply to func
   * @param function of (item, expressions[i])
   */
  mapFuncToString : function(string, expressions, func) {
    var self=this;
    var list = [string];
    for(var i=0, len=expressions.length; i<len; i++) {
        self.traverseListFunc(list, expressions[i], 0, func);
    }
    return self.flatten(list);
  },

  /**
   * Split a string
   * @param splitters Array of characters to apply the split
   */
  splitString : function(string, splitters) {
    return this.mapFuncToString(string, splitters, function(item, expression) {
      return item.split(expression);
    })
  },

}

然后

var stringToSplit = "people and_other/things";
var splitList = [" ", "_", "/"];
var splittedString=StringUtils.splitString(stringToSplit, splitList);
console.log(splitList, stringToSplit, splittedString);

归还原物的:

[ ' ', '_', '/' ] 'people and_other/things' [ 'people', 'and', 'other', 'things' ]

我不知道RegEx的性能如何,但这里有另一个RegEx的替代方案,它利用了本机HashSet,并在O(max(str)中工作。长度,delimeter.length))

var multiSplit = function(str,delimiter){
    if (!(delimiter instanceof Array))
        return str.split(delimiter);
    if (!delimiter || delimiter.length == 0)
        return [str];
    var hashSet = new Set(delimiter);
    if (hashSet.has(""))
        return str.split("");
    var lastIndex = 0;
    var result = [];
    for(var i = 0;i<str.length;i++){
        if (hashSet.has(str[i])){
            result.push(str.substring(lastIndex,i));
            lastIndex = i+1;
        }
    }
    result.push(str.substring(lastIndex));
    return result;
}

multiSplit('1,2,3.4.5.6 7 8 9',[',','.',' ']);
// Output: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]

multiSplit('1,2,3.4.5.6 7 8 9',' ');
// Output: ["1,2,3.4.5.6", "7", "8", "9"]

在Github上查看我的简单库

如果你真的不想访问或与repo交互,下面是工作代码:

/**
 * 
 * @param {type} input The string input to be split
 * @param {type} includeTokensInOutput If true, the tokens are retained in the splitted output.
 * @param {type} tokens The tokens to be employed in splitting the original string.
 * @returns {Scanner}
 */
function Scanner(input, includeTokensInOutput, tokens) {
    this.input = input;
    this.includeTokensInOutput = includeTokensInOutput;
    this.tokens = tokens;
}

Scanner.prototype.scan = function () {
    var inp = this.input;

    var parse = [];
    this.tokens.sort(function (a, b) {
        return b.length - a.length; //ASC, For Descending order use: b - a
    });
    for (var i = 0; i < inp.length; i++) {


        for (var j = 0; j < this.tokens.length; j++) {

            var token = this.tokens[j];
            var len = token.length;
            if (len > 0 && i + len <= inp.length) {
                var portion = inp.substring(i, i + len);
                if (portion === token) {
                    if (i !== 0) {//avoid empty spaces
                        parse[parse.length] = inp.substring(0, i);
                    }
                    if (this.includeTokensInOutput) {
                        parse[parse.length] = token;
                    }
                    inp = inp.substring(i + len);
                    i = -1;
                    break;
                }

            }

        }

    }
    if (inp.length > 0) {
          parse[parse.length] = inp;
    }

    return parse;


};

用法很简单:

    var tokens = new Scanner("ABC+DE-GHIJK+LMNOP", false , new Array('+','-')).scan();

console.log(tokens); 

给:

['ABC', 'DE', 'GHIJK', 'LMNOP']

如果您希望在输出中包含分隔令牌(+和-),将false设置为true,瞧!它仍然有效。

现在的用法是:

var tokens = new Scanner("ABC+DE-GHIJK+LMNOP", true , new Array('+','-')).scan();

and

console.log(tokens);

将:

['ABC', '+', 'DE', '-', 'GHIJK', '+', 'LMNOP']

享受吧!

你可以将一个正则表达式传递给JavaScript的split()方法。例如:

"1,2 3".split(/,| /) 
["1", "2", "3"]

或者,如果你想让多个分隔符一起只起到一个作用:

"1, 2, , 3".split(/(?:,| )+/) 
["1", "2", "3"]

您必须使用非捕获(?:)括号,因为 否则它会被拼接回结果中。或者你可以聪明一点 比如Aaron,使用一个角色类。

在Safari和Firefox中测试的示例。

不是最好的方法,但适用于使用多个和不同的分隔符/分隔符进行分割

html

<button onclick="myFunction()">Split with Multiple and Different seperators/delimiters</button>
<p id="demo"></p>

javascript

<script>
function myFunction() {

 var str = "How : are | you doing : today?";
 var res = str.split(' | ');

 var str2 = '';
 var i;
 for (i = 0; i < res.length; i++) { 
    str2 += res[i];
    
    if (i != res.length-1) {
      str2 += ",";
    }
 }
 var res2 = str2.split(' : ');

 //you can add countless options (with or without space)

 document.getElementById("demo").innerHTML = res2;
}
</script>