JavaScript正则表达式 - 分割字符串

15

遇到了一个正则表达式的要求。我需要将一个字符串分割成一个数组,每当发现斜杠时就进行分割。但如果斜杠前面有转义字符,则不进行分割。

例如,如果我有这个字符串:

hello/world

我希望它被拆分为像这样的数组:

arrayName[0] = hello
arrayName[1] = world

如果我有这个字符串:

hello/wo\/rld

我希望把它分割成数组,就像这样:

arrayName[0] = hello
arrayName[1] = wo/rld

有任何想法吗?


这个页面可能会有所帮助:http://blog.stevenlevithan.com/archives/mimic-lookbehind-javascript。我没有时间为您提供特定需求的示例,因此不会将其发布为*答案*。但我相信您可以从那篇文章中找到解决方法。祝你好运。 - T.J. Crowder
7个回答

23

我不会使用split()来完成这个任务。匹配路径组件本身要比匹配分隔符容易得多。例如:

var subject = 'hello/wo\\/rld';
var regex = /(?:[^\/\\]+|\\.)+/g;
var matched = null;
while (matched = regex.exec(subject)) {
  print(matched[0]);
}

输出:

hello
wo\/rld

在ideone.com上测试它


2
这对我来说看起来是最好的答案。 - Tim Down
1
同意。绝对是最好的答案。 - Yobert

3
这里有一种方式改编自这篇博客文章中介绍的技巧:
var str = "Testing/one\\/two\\/three";
var result = str.replace(/(\\)?\//g, function($0, $1){
  return $1 ? '/' : '[****]';
}).split('[****]');

现场示例

给定:

Testing/one\/two\/three

结果如下:
[0]: Testing
[1]: one/two/three

首先使用简单的“伪”后置查找将/替换为[****],将\/替换为/,然后根据[****]值进行拆分。(显然,用不在字符串中的任何内容替换[****]。)


谢谢 :) 这是适合我的东西。 - WastedSpace

3
以下方法可能会有些啰嗦,但是能够正常运行,同时避免了使用正则表达式带来的IE分隔函数问题
function splitPath(str) {
    var rawParts = str.split("/"), parts = [];
    for (var i = 0, len = rawParts.length, part; i < len; ++i) {
        part = "";
        while (rawParts[i].slice(-1) == "\\") {
            part += rawParts[i++].slice(0, -1) + "/";
        }
        parts.push(part + rawParts[i]);
    }
    return parts;
}

var str = "hello/world\\/foo/bar";
alert( splitPath(str).join(",") );

谢谢!这似乎是我一直在寻找的解决方案。 - WastedSpace

1

/* 如果您从ajax响应或数据库查询中获取字符串, 也就是说,该字符串尚未被JavaScript解释, 您可以匹配没有斜杠或已转义斜杠的字符序列。 如果您在脚本中定义字符串,请转义转义并在匹配后删除它们。 */

var s='hello/wor\\/ld';
s=s.match(/(([^\/]*(\\\/)+)([^\/]*)+|([^\/]+))/g) || [s];
alert(s.join('\n'))
s.join('\n').replace(/\\/g,'')

/*  returned value: (String)
hello
wor/ld
*/

0

对于短代码,您可以使用反向引用来模拟负回顾后断言

function reverse(s){
  return s.split('').reverse().join('');
}

var parts = reverse(myString).split(/[/](?!\\(?:\\\\)*(?:[^\\]|$))/g).reverse();
for (var i = parts.length; --i >= 0;) { parts[i] = reverse(parts[i]); }

但为了效率,最好是在/[/]/上进行分割,然后遍历数组并重新连接具有转义结尾的元素。


0

类似这样的代码可能会为您解决此问题。

var str = "/hello/wo\\/rld/";
var split = str.replace(/^\/|\\?\/|\/$/g, function(match) {
  if (match.indexOf('\\') == -1) {
    return '\x00';
  }
  return match;
}).split('\x00');       

alert(split);

0

1
这对于Ruby可能很好,但似乎不适用于JavaScript,至少不适用于split:http://jsbin.com/ipote5 如果您想以其他方式使用它,我建议您发布一下。 - T.J. Crowder
2
请在此处发布解决方案,而不是在其他网站上。 - user113716
1
这个不行:"hello/wor\/rld".match(/([a-z]+(\\\/)?[a-z]+)/) => ["hello", "hello", undefined] - Justin Johnson
@Justin:如果你使用 g 标识符 str.match(/[a-z]+(\\\/)?[a-z]+/g);,它就能起作用,但是如果有多个 \/(或者任何其他小写字母以外的字符),它就会失败。 - user113716
1
因此,正如你所说,将解决方案发布在这里非常重要。 - Justin Johnson
哦,真是的,请将 / 替换为 @@@,按 / 分割并撤消替换。 - Mikhail

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接