正则表达式需要在“上拆分javascript字符串”|&引用;但不是",\|&引用;

正则表达式需要在“上拆分javascript字符串”|&引用;但不是",\|&引用;,javascript,regex,Javascript,Regex,我们希望在管道字符\的实例上拆分字符串,但如果该字符前面有转义字符(例如\\\),则不能拆分 我们希望看到以下字符串拆分为以下组件 1|2|3\|4|5 1 2 3\|4 5 我希望能够使用下面的javascript函数split,它接受一个正则表达式。我要把什么正则表达式传递给split?我们是跨平台的,如果可能的话,我们希望支持IE、FF和Chrome的当前版本和以前的版本(1个版本) 这并不漂亮,但它应该为您拆分列表: var output = input.replace(/(\\)?

我们希望在管道字符
\
的实例上拆分字符串,但如果该字符前面有转义字符(例如
\\\
),则不能拆分

我们希望看到以下字符串拆分为以下组件

1|2|3\|4|5

1
2
3\|4
5

我希望能够使用下面的javascript函数split,它接受一个正则表达式。我要把什么正则表达式传递给split?我们是跨平台的,如果可能的话,我们希望支持IE、FF和Chrome的当前版本和以前的版本(1个版本)

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

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

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

您要查找的是“匹配正则表达式后面的负面外观”

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

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

这将获取您的输入字符串,并替换所有不紧跟“\”字符的“|”字符,并将其替换为“\n”字符。

执行全局匹配(与词法分析器相同):

  • 匹配除
    \\
    \
  • 或者匹配任何转义字符
大概是这样的:

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

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

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

  • 匹配除
    \\
    \
  • 或者匹配任何转义字符
大概是这样的:

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

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

在我研究这个问题时,发布了一个regex解决方案。所以我继续写了一篇没有它的文章。我做了一些简单的基准测试,它稍微快一点(我希望它会慢一点…)

如果不使用Regex,我理解您的需求,那么这应该可以完成以下工作:

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

在我研究这个问题时,发布了一个正则表达式解决方案。所以我继续写了一篇没有它的文章。我做了一些简单的基准测试,它稍微快一点(我希望它会慢一点…)

如果不使用Regex,我理解您的需求,那么这应该可以完成以下工作:

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

MDN文档建议javascript REs支持先行断言,但不支持后视断言。有人知道这是否准确吗?因为在这里,lookbehind断言是一个微不足道的解决方案。@KevinBallard不幸的是,MDN是正确的。例如,请参阅MDN文档建议javascript REs支持先行断言,但不支持后视断言。有人知道这是否准确吗?因为在这里,lookbehind断言是一个微不足道的解决方案。@KevinBallard不幸的是,MDN是正确的。例如,请参见更短的:
返回$1 | |$0+'\n'
。但是这个解决方案有效吗?@elclanrs
$1
将是
,如果管道前面没有反斜杠,否则它将包含该字符。空字符串的计算结果为false。甚至更短:
返回$1 | |$0+'\n'
。但是这个解决方案有效吗?@elclanrs
$1
将是
,如果管道前面没有反斜杠,否则它将包含该字符。空字符串的计算结果为false。我想这是一个很好的方法。您可以做的另一件事是找到模式
[^\\]([|]
的匹配项,并保存所有不属于组(1)的内容。它的优点是正则表达式更容易理解。你能解释一下上面提供的表达式吗?我对regex和相关技术相当陌生。我想这是一个很好的方法。您可以做的另一件事是找到模式
[^\\]([|]
的匹配项,并保存所有不属于组(1)的内容。它的优点是正则表达式更容易理解。你能解释一下上面提供的表达式吗?我对regex和相关技术相当陌生。