代码之家  ›  专栏  ›  技术社区  ›  Blaise

用空格拆分字符串,保留带引号的段,允许使用转义引号

  •  23
  • Blaise  · 技术社区  · 14 年前

    我现在有这个正则表达式,可以用所有空格拆分字符串,除非它在一个带引号的段中:

    keywords = 'pop rock "hard rock"';
    keywords = keywords.match(/\w+|"[^"]+"/g);
    console.log(keywords); // [pop, rock, "hard rock"]
    

    但是,我也希望在关键字中有引号,比如:

    keywords = 'pop rock "hard rock" "\"dream\" pop"';
    

    这个应该会回来

    [pop, rock, "hard rock", "\"dream\" pop"]
    

    最简单的方法是什么?

    4 回复  |  直到 7 年前
        1
  •  28
  •   Kobi    7 年前

    您可以将regex更改为:

    keywords = keywords.match(/\w+|"(?:\\"|[^"])+"/g);
    

    而不是 [^"]+ 你有 (?:\\"|[^"])+ 它允许 \" 或其他字符,但不是无范围引用。

    一个重要的注意事项是,如果希望字符串包含一个斜杠,它应该是:

    keywords = 'pop rock "hard rock" "\\"dream\\" pop"'; //note the escaped slashes.
    

    而且,在 \w+ [^ ] + -例如,它将匹配单词 "ab*d" ,但不是 ab*d (不带引号)。考虑使用 [^"\s]+ 相反,这将匹配非空格。

        2
  •  3
  •   Tsuneo Yoshioka    7 年前

    ES6解决方案支持:

    • 按空格拆分,内引号除外
    • 删除引号,但不删除反斜杠转义引号
    • 转义引号变为引号
    • 可以在任何地方引用

    代码:

    keywords.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
    

    输出:

    [ 'pop', 'rock', 'hard rock', '"dream" pop' ]
    
        3
  •  1
  •   Casimir et Hippolyte    8 年前

    如果Kobi的答案在示例字符串中很好地工作,那么当有多个连续转义字符时就不会出现这种情况。 (反斜杠) 在提姆·彼得斯卡在评论中注意到这一点时,引用了两段话。为了处理这些情况,可以这样编写模式 (对于匹配方法) :

    (?=\S)[^"\s]*(?:"[^\\"]*(?:\\[\s\S][^\\"]*)*"[^"\s]*)*
    

    demo

    在哪里? (?=\S) 确保当前位置至少有一个非空白字符,因为下面描述了所有允许的子字符串 (包括引号之间的空格) 完全是可选的。

    细节:

    (?=\S)   # followed by a non-whitespace
    [^"\s]*  #"# zero or more characters that aren't a quote or a whitespace
    (?: # when a quoted substring occurs:
        "       #"# opening quote
        [^\\"]* #"# zero or more characters that aren't a quote or a backslash
        (?: # when a backslash is encountered:
            \\ [\s\S] # an escaped character (including a quote or a backslash)
            [^\\"]* #"#
        )*
        "         #"# closing quote
        [^"\s]*   #"#
    )*
    
        4
  •  0
  •   neolectron    8 年前

    我想指出我和你有同样的雷吉士,

    /\w+|"[^"]+"/g
    

    但它不适用于空的引用字符串,例如:

    "" "hello" "" "hi"
    

    所以我不得不用*来改变+量词。 这给了我:

    str.match(/\w+|"[^"]*"/g);
    

    很好。

    (EX: https://regex101.com/r/wm5puK/1 )