1

我们想在管道字符的实例上分割一个字符串|,但如果该字符前面有一个转义字符,例如\|.

例如,我们希望将以下字符串拆分为以下组件

1|2|3\|4|5

1
2
3\|4
5

我希望能够使用以下 javascript 函数 split,它采用正则表达式。我会通过什么正则表达式来拆分?我们是跨平台的,如果可能的话,我们希望支持 IE、FF 和 Chrome 的当前和以前的版本(1 个版本)。

4

3 回答 3

9

而不是拆分,而是进行全局匹配(与词法分析器相同的方式):

  • 匹配除\\或以外的任何内容|
  • 或匹配任何转义字符

像这样的东西:

var str = "1|2|3\\|4|5";
var matches = str.match(/([^\\|]|\\.)+/g);

快速解释:([^\\|]|\\.)匹配除'\'and '|'(pattern: [^\\|]) 或 (pattern: |) 之外的任何字符,它匹配任何转义字符 (pattern: \\.)。+after 它告诉它匹配前一个一次或多次:因此该模式将([^\\|]|\\.)匹配一次或多次。正g则表达式文字末尾的 告诉 JavaScript 正则表达式引擎全局匹配模式,而不是只匹配一次。

于 2012-10-05T21:52:10.050 回答
1

您正在寻找的是“负后视匹配正则表达式”。

这并不漂亮,但它应该为您拆分列表:

var output = input.replace(/(\\)?|/g, function($0,$1){ return $1?$1:$0+'\n';});

这将获取您的输入字符串并替换所有的 '|' 字符前不紧跟 '\' 字符并将它们替换为 '\n' 字符。

于 2012-10-05T21:44:29.413 回答
0

当我正在研究这个时,发布了一个正则表达式解决方案。所以我只是继续写了一个没有它的东西。我做了一些简单的基准测试,它 - 稍微 - 更快(我预计它会更慢......)。

在不使用正则表达式的情况下,如果我理解您的需求,这应该可以完成工作:

function doSplit(input) {
    var output = [];
    var currPos = 0,
        prevPos = -1;
    while ((currPos = input.indexOf('|', currPos + 1)) != -1) {
        if (input[currPos-1] == "\\") continue;
        var recollect = input.substr(prevPos + 1, currPos - prevPos - 1);
        prevPos = currPos;
        output.push(recollect);
    }
    var recollect = input.substr(prevPos + 1);
    output.push(recollect);
    return output;
}
doSplit('1|2|3\\|4|5'); //returns [ '1', '2', '3\\|4', '5' ]
于 2012-10-05T22:06:17.840 回答