如何在javascript中拆分包含多个分隔符的字符串?

454 javascript regex split

如何在JavaScript中拆分包含多个分隔符的字符串?我试图在逗号和空格上分开但是,AFAIK,JS的分割功能只支持一个分隔符.

Aar*_*paa 650

传入正则表达式作为参数:

js> "Hello awesome, world!".split(/[\s,]+/)
Hello,awesome,world!
Run Code Online (Sandbox Code Playgroud)

编辑添加:

您可以通过选择数组长度减1来获取最后一个元素:

>>> bits = "Hello awesome, world!".split(/[\s,]+/)
["Hello", "awesome", "world!"]
>>> bit = bits[bits.length - 1]
"world!"
Run Code Online (Sandbox Code Playgroud)

......如果模式不匹配:

>>> bits = "Hello awesome, world!".split(/foo/)
["Hello awesome, world!"]
>>> bits[bits.length - 1]
"Hello awesome, world!"
Run Code Online (Sandbox Code Playgroud)

  • 你的 js> 控制台用的是什么? (4认同)
  • rhino,Mozilla在Java中实现JavaScript:http://www.mozilla.org/rhino/(...或"sudo apt-get install rhino"). (4认同)
  • 有没有办法避免在使用正则表达式拆分时删除分隔符? (2认同)

Jes*_*sak 169

您可以将正则表达式传递给Javascript的拆分运算符.例如:

"1,2 3".split(/,| /) 
["1", "2", "3"]
Run Code Online (Sandbox Code Playgroud)

或者,如果您希望允许多个分隔符一起仅作为一个:

"1, 2, , 3".split(/(?:,| )+/) 
["1", "2", "3"]
Run Code Online (Sandbox Code Playgroud)

(你必须使用非捕获(?:) parens,否则它会被拼接回到结果中.或者你可以像Aaron一样聪明并使用一个字符类.)

(在Safari + FF中测试的示例)

  • 如果您需要多个字符作为一个字符,例如"one; #two; #new jersey",您只需将字符串";#"传递给split函数即可."一个; #two; #new jersey".split(";#")[2] ==="新泽西" (3认同)

Bri*_*ian 49

另一种简单但有效的方法是重复使用split + join.

"a=b,c:d".split('=').join(',').split(':').join(',').split(',')
Run Code Online (Sandbox Code Playgroud)

基本上执行拆分后跟一个连接就像一个全局替换,所以用一个逗号替换每个分隔符然后一旦被替换它就会在逗号上进行最后一次拆分

上述表达式的结果是:

['a', 'b', 'c', 'd']
Run Code Online (Sandbox Code Playgroud)

扩展这个你也可以把它放在一个函数中:

function splitMulti(str, tokens){
        var tempChar = tokens[0]; // We can use the first token as a temporary join character
        for(var i = 1; i < tokens.length; i++){
            str = str.split(tokens[i]).join(tempChar);
        }
        str = str.split(tempChar);
        return str;
}
Run Code Online (Sandbox Code Playgroud)

用法:

splitMulti('a=b,c:d', ['=', ',', ':']) // ["a", "b", "c", "d"]
Run Code Online (Sandbox Code Playgroud)

如果你使用这个功能很多,甚至可能值得考虑包装 String.prototype.split以方便使用(我认为我的函数是相当安全的 - 唯一的考虑因素是条件(次要)的额外开销以及它缺少limit参数的实现这一事实如果传递一个数组).

splitMulti如果使用这种方法,请确保包含该功能,只需将其包装:).还值得注意的是,有些人不喜欢扩展内置插件(因为很多人做错了,可能会发生冲突),所以如果有疑问,请在使用之前与更高级的人交谈或者询问SO :)

    var splitOrig = String.prototype.split; // Maintain a reference to inbuilt fn
    String.prototype.split = function (){
        if(arguments[0].length > 0){
            if(Object.prototype.toString.call(arguments[0]) == "[object Array]" ) { // Check if our separator is an array
                return splitMulti(this, arguments[0]);  // Call splitMulti
            }
        }
        return splitOrig.apply(this, arguments); // Call original split maintaining context
    };
Run Code Online (Sandbox Code Playgroud)

用法:

var a = "a=b,c:d";
    a.split(['=', ',', ':']); // ["a", "b", "c", "d"]

// Test to check that the built-in split still works (although our wrapper wouldn't work if it didn't as it depends on it :P)
        a.split('='); // ["a", "b,c:d"] 
Run Code Online (Sandbox Code Playgroud)

请享用!

  • 你为什么写`for(var i = 0; i <tokens.length; i ++)`而不是`for(var i = 1; i <tokens.length; i ++)`? (3认同)
  • @BrodaNoel,你是对的,这是第一个代码示例的一个主要警告。在这种特殊情况下,最好使用可以安全分割的字符,在我的示例中,目的是替换 `,`,因此它是“安全的”,但确实需要注意。`splitMulti` 示例通过使用数组中的第一个标记作为临时占位符来解决这个问题,因为我们知道我们希望替换所有这些标记,因此使用起来总是安全的:) (3认同)
  • 玩弄原型并不明智。由于优化发生在深层,因此开销考虑因素很难被意识到。您可能会在 C 中触发一个标志,表示“如果他们修改了原型,假设 X 不再安全,则针对各种函数回退到这个[慢得多]的代码路径”。看似“低开销”的东西最终可能会使原本优化的代码的执行速度减慢几个数量级。 (2认同)
  • 不好,因为如果字符串中已经有一个“,”,即使您不想要它,您也会被它分割。 (2认同)

Ash*_*her 17

让我们保持简单:(在您的RegEx中添加"[] +"表示"1或更多")

这意味着"+"和"{1,}"是相同的.

var words = text.split(/[ .:;?!~,`"&|()<>{}\[\]\r\n/\\]+/); // note ' and - are kept
Run Code Online (Sandbox Code Playgroud)

  • 我会说这很小,不简单 (5认同)
  • 在末尾添加"+"表示1或更多 (2认同)

小智 12

棘手的方法:

var s = "dasdnk asd, (naks) :d skldma";
var a = s.replace('(',' ').replace(')',' ').replace(',',' ').split(' ');
console.log(a);//["dasdnk", "asd", "naks", ":d", "skldma"]
Run Code Online (Sandbox Code Playgroud)

  • 您可以将 `'('` 更改为 `/(/g` 以替换所有 `(` 元素 - `g` 是 RegExp 的 *global* 标志 - 因此它搜索所有出现的 `(` 而不是第一个 (3认同)
  • 这是错误的,因为.replace()不会替换所有元素`:/` (2认同)

blo*_*wtf 12

我很惊讶还没有人建议这样做,但我的黑客(而且疯狂的快)解决方案是在按同一字符拆分之前附加几个“替换”调用。

即删除 a、b、c、d 和 e:

let str = 'afgbfgcfgdfgefg'
let array = str.replace('a','d').replace('b','d').replace('c','d').replace('e','d').split('d')
Run Code Online (Sandbox Code Playgroud)

这可以方便地推广到分离器阵列,如下所示:

function splitByMany( manyArgs, string ) {
  do {
    let arg = manyArgs.pop()
    string = string.replace(arg, manyArgs[0])
  } while (manyArgs.length > 2)
  return string.split(manyArgs[0])
}
Run Code Online (Sandbox Code Playgroud)

因此,就您的情况而言,您可以致电

let array = splitByMany([" ", ","], 'My long string containing commas, and spaces, and more commas');
Run Code Online (Sandbox Code Playgroud)


Ahm*_*agh 11

以下是使用正则表达式可能会有所帮助的一些情况:

  • \W匹配任何字符 else 单词 character [a-zA-Z0-9_]。例子:
("Hello World,I-am code").split(/\W+/); // would return [ 'Hello', 'World', 'I', 'am', 'code' ]
Run Code Online (Sandbox Code Playgroud)
  • \s+匹配一个或多个空格
  • \d匹配一个数字
  • 如果您想按某些字符分割,请告诉我们,-您可以使用str.split(/[,-]+/)...等


Ste*_*duk 7

对于那些想要在分割函数中进行更多自定义的人,我编写了一个递归算法,该算法将给定字符串与要拆分的字符列表分开.在看到上面的帖子之前我写了这个.我希望它可以帮助一些沮丧的程序员.

splitString = function(string, splitters) {
    var list = [string];
    for(var i=0, len=splitters.length; i<len; i++) {
        traverseList(list, splitters[i], 0);
    }
    return flatten(list);
}

traverseList = function(list, splitter, index) {
    if(list[index]) {
        if((list.constructor !== String) && (list[index].constructor === String))
            (list[index] != list[index].split(splitter)) ? list[index] = list[index].split(splitter) : null;
        (list[index].constructor === Array) ? traverseList(list[index], splitter, 0) : null;
        (list.constructor === Array) ? traverseList(list, splitter, index+1) : null;    
    }
}

flatten = function(arr) {
    return arr.reduce(function(acc, val) {
        return acc.concat(val.constructor === Array ? flatten(val) : val);
    },[]);
}

var stringToSplit = "people and_other/things";
var splitList = [" ", "_", "/"];
splitString(stringToSplit, splitList);
Run Code Online (Sandbox Code Playgroud)

以上示例返回: ["people", "and", "other", "things"]

注意:flatten功能取自Rosetta Code


Pet*_*rKA 6

您可以将要用作分隔符的所有字符单独或共同整合到正则表达式中,并将它们传递给split函数.比如你可以写:

console.log( "dasdnk asd, (naks) :d skldma".split(/[ \(,\)]+/) );
Run Code Online (Sandbox Code Playgroud)

输出将是:

["dasdnk", "asd", "naks", ":d", "skldma"]
Run Code Online (Sandbox Code Playgroud)


Vis*_*hnu 6

这是在ES6中实现相同目标的新方法:

function SplitByString(source, splitBy) {
  var splitter = splitBy.split('');
  splitter.push([source]); //Push initial value

  return splitter.reduceRight(function(accumulator, curValue) {
    var k = [];
    accumulator.forEach(v => k = [...k, ...v.split(curValue)]);
    return k;
  });
}

var source = "abc,def#hijk*lmn,opq#rst*uvw,xyz";
var splitBy = ",*#";
console.log(SplitByString(source, splitBy));
Run Code Online (Sandbox Code Playgroud)

在此函数中请注意:

  • 不涉及正则表达式
  • 以与出现的顺序相同的顺序返回分割值source

上述代码的结果将是:

在此输入图像描述


小智 6

我将提供此类函数的经典实现。该代码适用于几乎所有版本的 JavaScript,并且在某种程度上是最佳的。

  • 它不使用正则表达式,这很难维护
  • 它没有使用 JavaScript 的新功能
  • 它不使用需要更多计算机内存的多个 .split() .join() 调用

只是纯代码:

var text = "Create a function, that will return an array (of string), with the words inside the text";

println(getWords(text));

function getWords(text)
{
    let startWord = -1;
    let ar = [];
    
    for(let i = 0; i <= text.length; i++)
    {
        let c = i < text.length ? text[i] : " ";

        if (!isSeparator(c) && startWord < 0)
        {
            startWord = i;
        }
        
        if (isSeparator(c) && startWord >= 0)
        {
            let word = text.substring(startWord, i);
            ar.push(word);
            
            startWord = -1;
        }
    }

    return ar;
}

function isSeparator(c)
{
    var separators = [" ", "\t", "\n", "\r", ",", ";", ".", "!", "?", "(", ")"];
    return separators.includes(c);
}
Run Code Online (Sandbox Code Playgroud)


Jan*_*szO 6

我对@Brian 答案的重构

var string = 'and this is some kind of information and another text and simple and some egample or red or text';
var separators = ['and', 'or'];

function splitMulti(str, separators){
            var tempChar = 't3mp'; //prevent short text separator in split down
            
            //split by regex e.g. \b(or|and)\b
            var re = new RegExp('\\b(' + separators.join('|') + ')\\b' , "g");
            str = str.replace(re, tempChar).split(tempChar);
            
            // trim & remove empty
            return str.map(el => el.trim()).filter(el => el.length > 0);
}

console.log(splitMulti(string, separators))
Run Code Online (Sandbox Code Playgroud)


小智 5

嗨,例如,如果您在字符串 07:05:45PM 中拆分和替换

var hour = time.replace("PM", "").split(":");
Run Code Online (Sandbox Code Playgroud)

结果

[ '07', '05', '45' ]
Run Code Online (Sandbox Code Playgroud)


Imr*_*ran 5

按.com/.net/分割 URL

url.split(/\.com\/|\.net\//)
Run Code Online (Sandbox Code Playgroud)