如何在javascript中使用多个分隔符分割字符串?


504

如何在JavaScript中使用多个分隔符拆分字符串?我正在尝试在逗号和空格上进行拆分,但是AFAIK,JS的拆分功能仅支持一个分隔符。


3
我在尝试拆分Windows下使用nodejs构造的文件路径时遇到了这个问题。有时在同一路径中有正斜杠“ /”和反斜杠“ \”。
Fuhrmanator 2014年

Answers:


707

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

js> "Hello awesome, world!".split(/[\s,]+/)
Hello,awesome,world!

编辑添加:

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

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

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

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

1
您正在使用什么用于js>控制台?
核心

4
rhino,Mozilla在Java中对JavaScript的实现:mozilla.org/rhino(...或“ sudo apt-get install rhino”)。
亚伦·曼帕

谢谢。与此相关的另一个问题是我需要获取拆分数组的最后一个元素。如果没有数组,则应返回字符串thx

2
使用正则表达式拆分时,有什么方法可以避免删除分隔符?
安德森·格林

如何同时为字符串“ hello world”和另一个字符(或其他正则表达式)(如管道符号)拆分?尝试过的变种(hello world)|\|还没有奏效。有任何想法吗?
关于natty的坚果,2014年

183

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

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

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

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

(您必须使用非捕获(?:)括号,因为否则它会被拼接回结果中。或者您可以像Aaron一样聪明,并使用字符类。)

(示例在Safari + FF中测试)


3
如果您需要多个字符作为一个字符,例如说“ one; #two; #new jersey”,则只需将字符串“;#”传递给split函数。“一个; #two;#新球衣” .split(“;#”)[2] ===“新球衣”
Oskar Austegard 2010年

如果需要分割多个字符,则此方法比字符类更好。|如Jesse所示,将它们分开。
devios1 2012年

我想知道是否有一种方法可以避免在使用正则表达式拆分字符串时删除分隔符:此示例删除了分隔符,但我希望可以在不删除分隔符的情况下拆分字符串。
安德森·格林

1
@AndersonGreen这完全取决于您想要什么;在这种情况下,有多个分隔符,那么是否要保留所有分隔符?作为单独的项目?加入上一个项目吗?下一项?对我来说似乎不清楚。您可能想用一些您要寻找的例子来提出一个新问题。
杰西·鲁萨克

@JesseRusak我的意思是将所有分隔符保留为单独的项目,以便可以使用分隔符列表对字符串进行标记。
安德森·格林

55

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

"a=b,c:d".split('=').join(',').split(':').join(',').split(',')

本质上,先进行拆分再进行联接,就像全局替换一样,因此这将每个分隔符替换为逗号,然后在替换所有分隔符后对逗号进行最终拆分

上面表达式的结果是:

['a', 'b', 'c', 'd']

对此进行扩展,您还可以将其放置在函数中:

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;
}

用法:

splitMulti('a=b,c:d', ['=', ',', ':']) // ["a", "b", "c", "d"]

如果您经常使用此功能,甚至可能值得考虑包装 String.prototype.split以方便使用(我认为我的功能相当安全-唯一的考虑是条件(较小)的额外开销,以及它缺少limit参数实现的事实如果传递了数组)。

splitMulti如果对下面使用此方法只是将其包装起来,请确保包括该函数:)。还值得一提的是,有些人不愿扩展内置函数(因为很多人做错了,可能会发生冲突),因此如果有疑问,请在使用此函数之前先与更高级的人交谈或提出要求:)

    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
    };

用法:

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"] 

请享用!


3
为什么你写的for(var i = 0; i < tokens.length; i++),而不是for(var i = 1; i < tokens.length; i++)
tic

我错过了优化,您是对的,我们可以从开始tokens[1]保存一个迭代开始,tokens[0] == tempchar然后tempchar在迭代tokens完成后继续进行。我会相应地更新答案,谢谢@tic :)。
布莱恩

20

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

这意味着“ +”和“ {1,}”相同。

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

2
在末尾添加“ +”表示1个或多个
Asher 2015年

6
我会说这是最小的,而不是简单的
Darryl Hebbes 17-10-24

对于+和-:-D,也可以用\ s代替空白的char:var words = text.split(/ [\ s.:;?!~,`"&|()<>{}\= \ + \-[] \ r \ n / \] + /);
Didier68 '19

12

棘手的方法:

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

3
这是错误的,因为.replace()不会替换所有元素:/

1
你可以改变'('/(/g,以取代所有(元素- g全球性的正则表达式标志-因此它搜索的所有事件(不是一个第一
codename-

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);

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

注意:此flatten功能取自Rosetta Code


6

您可以将要用作分隔符的所有字符单独或共同打包到正则表达式中,然后将它们传递给split函数。例如,您可以编写:

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

输出将是:

["dasdnk", "asd", "naks", ":d", "skldma"]

3

也许您应该执行某种字符串替换操作,以将一个分隔符转换为另一个分隔符,这样您的拆分中就只能处理一个分隔符。


3

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

var hour = time.replace("PM", "").split(":");

结果

[ '07', '05', '45' ]

3

这是在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));

请注意此功能:

  • 不涉及正则表达式
  • 返回拆分值,其顺序与出现在其中的顺序相同 source

以上代码的结果将是:

在此处输入图片说明


2
a = "a=b,c:d"

array = ['=',',',':'];

for(i=0; i< array.length; i++){ a= a.split(array[i]).join(); }

这将返回没有特殊字符的字符串。


2

我对@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))


1

我发现我需要这样做的主要原因之一是要在/和上拆分文件路径\。这是一个棘手的正则表达式,所以我将其发布在这里以供参考:

var splitFilePath = filePath.split(/[\/\\]/);

1

我认为,如果您指定要离开的内容,而不是要删除的内容,会更容易。

如果您只想使用英语单词,则可以使用以下内容:

text.match(/[a-z'\-]+/gi);

示例(运行摘要):

var R=[/[a-z'\-]+/gi,/[a-z'\-\s]+/gi];
var s=document.getElementById('s');
for(var i=0;i<R.length;i++)
 {
  var o=document.createElement('option');
  o.innerText=R[i]+'';
  o.value=i;
  s.appendChild(o);
 }
var t=document.getElementById('t');
var r=document.getElementById('r');

s.onchange=function()
 {
  r.innerHTML='';
  var x=s.value;
  if((x>=0)&&(x<R.length))
   x=t.value.match(R[x]);
  for(i=0;i<x.length;i++)
   {
    var li=document.createElement('li');
    li.innerText=x[i];
    r.appendChild(li);
   }
 }
<textarea id="t" style="width:70%;height:12em">even, test; spider-man

But saying o'er what I have said before:
My child is yet a stranger in the world;
She hath not seen the change of fourteen years,
Let two more summers wither in their pride,
Ere we may think her ripe to be a bride.

—Shakespeare, William. The Tragedy of Romeo and Juliet</textarea>

<p><select id="s">
 <option selected>Select a regular expression</option>
 <!-- option value="1">/[a-z'\-]+/gi</option>
 <option value="2">/[a-z'\-\s]+/gi</option -->
</select></p>
 <ol id="r" style="display:block;width:auto;border:1px inner;overflow:scroll;height:8em;max-height:10em;"></ol>
</div>


1

从@ 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' ]

1

一种简单的方法是使用每个定界符处理字符串的每个字符并构建拆分数组:

splix = function ()
{
  u = [].slice.call(arguments); v = u.slice(1); u = u[0]; w = [u]; x = 0;

  for (i = 0; i < u.length; ++i)
  {
    for (j = 0; j < v.length; ++j)
    {
      if (u.slice(i, i + v[j].length) == v[j])
      {
        y = w[x].split(v[j]); w[x] = y[0]; w[++x] = y[1];
      };
    };
  };

  return w;
};

用法: splix(string, delimiters...)

例: splix("1.23--4", ".", "--")

返回值: ["1", "23", "4"]


1

我将提供此类功能的经典实现。该代码几乎可以在所有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);
}

您可以看到在操场上运行的代码:https : //codeguppy.com/code.html?IJI0E4OGnkyTZnoszAzf


0

我不知道RegEx的性能,但是这是RegEx的另一种选择,它利用本机HashSet并以O(max(str.length,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"]

11
是的,您实际上如何测试自己编写的内容?jsperf.com/slice-vs-custom 这表明在此示例中,您的代码实际上慢了10倍。是什么让您认为使用2倍切片,2倍连续,1次拆分,1次移位和不进行长度缓存对性能友好的?
Petar 2014年

我更新的代码,现在有切片的没有移位,分割或仅等最小量
Orhun阿尔卑斯口腔

0

这不是最佳方法,但是可以使用多个不同的分隔符/分隔符进行拆分

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>

-3

我使用regexp:

str =  'Write a program that extracts from a given text all palindromes, e.g. "ABBA", "lamal", "exe".';

var strNew = str.match(/\w+/g);

// Output: ["Write", "a", "program", "that", "extracts", "from", "a", "given", "text", "all", "palindromes", "e", "g", "ABBA", "lamal", "exe"]

1
这对回文论不起作用,而只是言语。
内森·塔吉
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.