【问题标题】:Javascript split string on space or on quotes to arrayJavascript在空格或引号上拆分字符串到数组
【发布时间】:2010-05-12 09:52:09
【问题描述】:
var str = 'single words "fixed string of words"';
var astr = str.split(" "); // need fix

我希望数组是这样的:

var astr = ["single", "words", "fixed string of words"];

【问题讨论】:

    标签: javascript regex split


    【解决方案1】:

    接受的答案并不完全正确。它在非空格字符上分隔,例如 .和 - 并在结果中留下引号。这样做以排除引号的更好方法是捕获组,如下所示:

    //The parenthesis in the regex creates a captured group within the quotes
    var myRegexp = /[^\s"]+|"([^"]*)"/gi;
    var myString = 'single words "fixed string of words"';
    var myArray = [];
    
    do {
        //Each call to exec returns the next regex match as an array
        var match = myRegexp.exec(myString);
        if (match != null)
        {
            //Index 1 in the array is the captured group if it exists
            //Index 0 is the matched text, which we use if no captured group exists
            myArray.push(match[1] ? match[1] : match[0]);
        }
    } while (match != null);
    

    myArray 现在将包含 OP 要求的内容:

    single,words,fixed string of words
    

    【讨论】:

    • 效果很好,谢谢。只是说“i”开关看起来是多余的。
    • var myRegexp = [^\s"]+|"(?:\\"|[^"])*"/g ...允许 \" (引号内的转义引号)
    • 我发布了一个问题,询问确切的问题,后来在更专门的搜索发现这个出色的答案后将其删除(没有回复/答案)。如前所述,上面的解决方案完全按照 OP 的要求('apple banana "nova scotia" "british columbia"' >> "apple", "banana", "nova scotia", "british columbia" - 我学到了一些新的即即 JavaScript!:-)
    【解决方案2】:
    str.match(/\w+|"[^"]+"/g)
    
    //single, words, "fixed string of words"
    

    【讨论】:

    • 这似乎在'。'和 '-' 以及空格。这应该是str.match(/\S+|"[^"]+"/g)
    • 如果它必须处理转义引号,还有另一个问题。例如:'single words "fixed string of \"quoted\" words"' 即使有了 Awalias 的更正,这给出了:["single", "words", ""fixed", "string", ""of", "words""] 您需要处理转义的引号,但不要绊倒并抓住和转义的反斜杠。我认为它最终会变得比你真正想用正则表达式处理的更复杂。
    • @Awalias 我在下面有一个更好的答案。您的正则表达式示例实际上应该是 /[^\s"]+|"([^"]*)"/g.你的仍然会在引用区域的空格上分开。我添加了一个解决此问题的答案,并从 OP 要求的结果中删除了引号。
    • 如果您想允许转义引号,请参阅this other SO question
    【解决方案3】:

    这使用了拆分和正则表达式匹配的混合。

    var str = 'single words "fixed string of words"';
    var matches = /".+?"/.exec(str);
    str = str.replace(/".+?"/, "").replace(/^\s+|\s+$/g, "");
    var astr = str.split(" ");
    if (matches) {
        for (var i = 0; i < matches.length; i++) {
            astr.push(matches[i].replace(/"/g, ""));
        }
    }
    

    这将返回预期的结果,尽管单个正则表达式应该能够完成所有操作。

    // ["single", "words", "fixed string of words"]
    

    更新 这是S.Mark提出的方法的改进版

    var str = 'single words "fixed string of words"';
    var aStr = str.match(/\w+|"[^"]+"/g), i = aStr.length;
    while(i--){
        aStr[i] = aStr[i].replace(/"/g,"");
    }
    // ["single", "words", "fixed string of words"]
    

    【讨论】:

    • 改进版有一个问题,如果你使用像“#”这样的非单词字符,它会消失。
    • 这是一个很好的答案,但是如果您想通过正则表达式完成所有操作并删除引号,我添加了一个新的答案来执行此操作并且不需要循环遍历每个结果以去除之后的引号。
    【解决方案4】:

    这可能是一个完整的解决方案: https://github.com/elgs/splitargs

    【讨论】:

      【解决方案5】:

      ES6 方案支持:

      • 除内引号外按空格分隔
      • 删除引号,但不删除反斜杠转义引号
      • 转义的引号变成引号
      • 可以在任何地方加上引号

      代码:

      str.match(/\\?.|^$/g).reduce((p, c) => {
              if(c === '"'){
                  p.quote ^= 1;
              }else if(!p.quote && c === ' '){
                  p.a.push('');
              }else{
                  p.a[p.a.length-1] += c.replace(/\\(.)/,"$1");
              }
              return  p;
          }, {a: ['']}).a
      

      输出:

      [ 'single', 'words', 'fixed string of words' ]
      

      【讨论】:

        【解决方案6】:

        这会将其拆分为一个数组,并从任何剩余的字符串中去除周围的引号。

        const parseWords = (words = '') =>
            (words.match(/[^\s"]+|"([^"]*)"/gi) || []).map((word) => 
                word.replace(/^"(.+(?="$))"$/, '$1'))

        【讨论】:

          【解决方案7】:

          此解决方案适用于双引号 (") 和单引号 ('):

          代码

          str.match(/[^\s"']+|"([^"]*)"/gmi)
          
          // ["single", "words", "fixed string of words"]
          

          这里显示了这个正则表达式的工作原理:https://regex101.com/r/qa3KxQ/2

          【讨论】:

            【解决方案8】:

            直到我找到@dallin 的答案(此线程:https://stackoverflow.com/a/18647776/1904943)我在通过 JavaScript 处理混合了未引用和引用的术语/短语的字符串时遇到了困难。

            在研究这个问题时,我进行了许多测试。

            由于我发现很难找到这些信息,我整理了相关信息(如下),这可能对其他寻求在 JavaScript 中处理包含引号的单词的字符串的答案的人有用。


            let q = 'apple banana "nova scotia" "british columbia"';
            

            提取[仅]引用的单词和短语:

            // https://stackoverflow.com/questions/12367126/how-can-i-get-a-substring-located-between-2-quotes
            const r = q.match(/"([^']+)"/g);
            console.log('r:', r)
            // r: Array [ "\"nova scotia\" \"british columbia\"" ]
            console.log('r:', r.toString())
            // r: "nova scotia" "british columbia"
            
            // ----------------------------------------
            
            // [alternate regex] https://www.regextester.com/97161
            const s = q.match(/"(.*?)"/g);
            console.log('s:', s)
            // s: Array [ "\"nova scotia\"", "\"british columbia\"" ]
            console.log('s:', s.toString())
            // s: "nova scotia","british columbia"
            

            提取 [all] 未引用、引用的单词和短语:

            // https://stackoverflow.com/questions/2817646/javascript-split-string-on-space-or-on-quotes-to-array
            const t = q.match(/\w+|"[^"]+"/g);
            console.log('t:', t)
            // t: Array(4) [ "apple", "banana", "\"nova scotia\"", "\"british columbia\"" ]
            console.log('t:', t.toString())
            // t: apple,banana,"nova scotia","british columbia"
            
            // ----------------------------------------------------------------------------
            
            // https://stackoverflow.com/questions/2817646/javascript-split-string-on-space-or-on-quotes-to-array
            // [@dallon 's answer (this thread)] https://stackoverflow.com/a/18647776/1904943
            
            var myRegexp = /[^\s"]+|"([^"]*)"/gi;
            var myArray = [];
            
            do {
                /* Each call to exec returns the next regex match as an array. */
                var match = myRegexp.exec(q);    // << "q" = my query (string)
                if (match != null)
                {
                    /* Index 1 in the array is the captured group if it exists.
                     * Index 0 is the matched text, which we use if no captured group exists. */
                    myArray.push(match[1] ? match[1] : match[0]);
                }
            } while (match != null);
            
            console.log('myArray:', myArray, '| type:', typeof(myArray))
            // myArray: Array(4) [ "apple", "banana", "nova scotia", "british columbia" ] | type: object
            console.log(myArray.toString())
            // apple,banana,nova scotia,british columbia
            

            使用集合(而不是数组):

            // https://stackoverflow.com/questions/28965112/javascript-array-to-set
            var mySet = new Set(myArray);
            console.log('mySet:', mySet, '| type:', typeof(mySet))
            // mySet: Set(4) [ "apple", "banana", "nova scotia", "british columbia" ] | type: object
            

            迭代集合元素:

            mySet.forEach(x => console.log(x));
            /* apple
             * banana
             * nova scotia
             * british columbia
             */
            
            // https://stackoverflow.com/questions/16401216/iterate-over-set-elements
            myArrayFromSet = Array.from(mySet);
            
            for (let i=0; i < myArrayFromSet.length; i++) {
                console.log(i + ':', myArrayFromSet[i])
            }
            /*
             0: apple
             1: banana
             2: nova scotia
             3: british columbia 
             */
            

            旁白

            • 上面的 JavaScript 响应来自 FireFox 开发者工具(F12,来自网页)。我创建了一个空白 HTML 文件,该文件调用了我用 Vim 编辑的 .js 文件,作为我的 IDE。 Simple JavaScript IDE

            • 根据我的测试,克隆集似乎是深层副本。 Shallow-clone an ES6 Map or Set

            【讨论】:

              【解决方案9】:

              我也注意到消失的字符。我认为您可以包含它们 - 例如,要让它在单词中包含“+”,请使用“[\w\+]”之类的东西,而不仅仅是“\w”。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-11-26
                • 2015-11-09
                • 2013-02-17
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多