簡體   English   中英

如何在 JavaScript 中拆分具有多個分隔符的字符串?

[英]How do I split a string with multiple separators in JavaScript?

如何在 JavaScript 中拆分具有多個分隔符的字符串?

我正在嘗試拆分逗號空格,但 AFAIK JavaScript 的split() function 僅支持一個分隔符。

傳入一個正則表達式作為參數:

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

您可以將正則表達式傳遞給 JavaScript 的split()方法。 例如:

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

或者,如果您想讓多個分隔符一起作為一個分隔符:

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

(您必須使用非捕獲(?:)括號,否則它會被拼接回結果中。或者您可以像 Aaron 一樣聰明並使用字符 class。)

在 Safari 和 Firefox 中測試的示例。

另一種簡單但有效的方法是重復使用 split + join。

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

本質上,先進行拆分,然后進行連接就像全局替換,所以這會用逗號替換每個分隔符,然后一旦全部替換,它會在逗號上進行最終拆分

上述表達式的結果是:

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

對此進行擴展,您還可以將其放在 function 中:

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為方便起見(我認為我的 function 相當安全 - 唯一需要考慮的是條件(次要)的額外開銷以及它缺少如果傳遞了數組,則執行限制參數)。

如果使用下面的這種方法簡單地包裝它,請務必包含splitMulti function :)。 還值得注意的是,有些人不贊成擴展內置插件(因為很多人做錯了並且可能發生沖突),所以如果有疑問,請在使用此插件之前與更資深的人交談或詢問 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
    };

用法:

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

享受!

讓我們保持簡單:(在您的 RegEx 中添加“[ ]+”表示“1 或更多”)

這意味着“+”和“{1,}”是相同的。

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

棘手的方法:

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

對於那些想要在拆分 function 時進行更多自定義的人,我編寫了一個遞歸算法,該算法將給定的字符串拆分為要拆分的字符列表。 我在看到上面的帖子之前寫了這個。 我希望它可以幫助一些沮喪的程序員。

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 function 取自Rosetta Code

您可以將所有要用作分隔符的字符單獨或集中匯總到正則表達式中,然后將它們傳遞給拆分 function。 例如你可以寫:

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

output 將是:

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

我對@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 eg \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))

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

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

結果

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

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

請注意此 function:

  • 不涉及正則表達式
  • 以與source中出現的順序相同的順序返回拆分值

上述代碼的結果將是:

在此處輸入圖像描述

我將為這樣的 function 提供一個經典的實現。 該代碼幾乎適用於 JavaScript 的所有版本,並且在某種程度上是最佳的。

  • 它不使用難以維護的正則表達式
  • 它不使用 JavaScript 的新功能
  • 它不使用需要更多計算機 memory 的 multiple.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);
}

您可以看到在 Playground 中運行的代碼: https://codeguppy.com/code.html?IJI0E4OGnkyTZnoszAzf

a = "a=b,c:d"

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

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

這將返回沒有特殊字符的字符串。

通過.com/.net/拆分 URL

url.split(/\.com\/|\.net\//)

也許您應該進行某種字符串替換以將一個分隔符轉換為另一個分隔符,這樣您就只有一個分隔符在您的拆分中處理。

以下是一些使用正則表達式可能會有所幫助的案例:

  • \W匹配任何字符,否則單詞字符[a-zA-Z0-9_] 例子:
("Hello World,I-am code").split(/\W+/); // would return [ 'Hello', 'World', 'I', 'am', 'code' ]
  • \s+匹配一個或多個空格
  • \d匹配一個數字
  • 如果你想用一些字符分割,只讓我們說,並且-你可以使用str.split(/[,-]+/) ...等

我認為如果您指定要留下的內容而不是要刪除的內容會更容易。

好像你只想有英文單詞,你可以使用這樣的東西:

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>

我在尋找 C# string.Split() function 的替代品時遇到了這個問題,它使用其參數中的字符拆分字符串。

在 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() 用於展平中間結果,因此每次迭代都在沒有嵌套 arrays 的字符串列表上工作。 每次迭代都將 split 應用於 old 中的所有值,然后返回中間結果列表,這些結果將被拆分器中的下一個值拆分。 reduce() 使用包含初始字符串值的數組進行初始化。

我不知道 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"]

我發現我需要這個的主要原因之一是在/\上拆分文件路徑。 這有點棘手的正則表達式,所以我會在這里發布以供參考:

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

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

一個簡單的方法是使用每個分隔符處理字符串的每個字符並構建一個拆分數組:

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

 console.logg = function () { document.body.innerHTML += "<br>" + [].slice.call(arguments).join(); } splix = function() { u = [].slice.call(arguments); v = u.slice(1); u = u[0]; w = [u]; x = 0; console.logg("Processing: <code>" + JSON.stringify(w) + "</code>"); for (i = 0; i < u.length; ++i) { for (j = 0; j < v.length; ++j) { console.logg("Processing: <code>[\x22" + u.slice(i, i + v[j].length) + "\x22, \x22" + v[j] + "\x22]</code>"); if (u.slice(i, i + v[j].length) == v[j]) { y = w[x].split(v[j]); w[x] = y[0]; w[++x] = y[1]; console.logg("Currently processed: " + JSON.stringify(w) + "\n"); }; }; }; console.logg("Return: <code>" + JSON.stringify(w) + "</code>"); }; setTimeout(function() { console.clear(); splix("1.23--4", ".", "--"); }, 250);
 @import url("http://fonts.googleapis.com/css?family=Roboto"); body {font: 20px Roboto;}

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

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

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

我通過減少和過濾解決了這個問題。 它可能不是最易讀的解決方案,也不是最快的解決方案,在現實生活中我可能會在這里使用 Aarons answere ,但寫起來很有趣。

[' ','_','-','.',',',':','@'].reduce(
(segs, sep) => segs.reduce(
(out, seg) => out.concat(seg.split(sep)), []), 
['E-mail Address: user@domain.com, Phone Number: +1-800-555-0011']
).filter(x => x)

或作為 function:

function msplit(str, seps) {
  return seps.reduce((segs, sep) => segs.reduce(
    (out, seg) => out.concat(seg.split(sep)), []
  ), [str]).filter(x => x);
}

這將 output:

['E','mail','Address','user','domain','com','0','Phone','Number','+1','800','555','0011']

如果最后沒有過濾器,您將在數組中獲得空字符串,其中兩個不同的分隔符彼此相鄰。

不是最好的方法,但可以使用多個不同的分隔符/分隔符進行拆分

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>

我很驚訝還沒有人建議它,但我的hack-ey(和瘋狂的快速)解決方案只是 append 幾個“替換”調用,然后由相同的字符分割。

即刪除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')

這可以方便地概括為拆分器數組,如下所示:

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

所以,在你的情況下,你可以打電話

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

查看我在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']

如果您希望在 output 中包含拆分標記(+ and -) ,請將false設置為true ,然后瞧。 它仍然有效。

現在的用法是:

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

console.log(tokens);

會給:

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

請享用!

我使用正則表達式:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM