2012-03-24 162 views
2

的阵列中的给定像在JavaScript以下分割字符串,但保留分隔符拆分

var a = 'hello world\n\nbye world\n\nfoo\nbar\n\nfoo\nbaz\n\n'; 

我想把它分成数组这样

['hello world', '\n\n', 'bye world', '\n\n', 'foo\nbar', '\n\n', 'foo\nbaz', '\n\n']. 

如果输入var a = 'hello world\n\nbye world'字符串,结果应该是['hello world', '\n\n', 'bye world']

换句话说,我想将'\ n \ n'周围的字符串拆分成一个数组,这样数组也包含'\ n \ n'。有没有什么好办法在JavaScript中做到这一点?

+0

你想要什么''\ n \ n \ n \ nb''拆分成什么? – Cameron 2012-03-24 19:24:52

+0

@AdamZalcman我已经尝试在字符串上运行一个循环,并使用'indexOf'和'substr'函数来提取我想要的东西,但是我想知道是否有更好的方法来解决这个问题。 – 2012-03-24 19:27:20

+0

@Cameron对我来说,两者都不错:['a','\ n \ n','b']和['a','\ n \ n','\ n \ n','b “]。这个输出对于我的特殊情况来说并不重要,所以我们可以选择哪个导致更优雅的代码。 – 2012-03-24 19:29:28

回答

3

这里是一个班轮:

str.match(/\n\n|(?:[^\n]|\n(?!\n))+/g) 

下面是它如何工作的:

  • \n\n两个连续的换行字符匹配
  • (?:[^\n]|\n(?!\n))+比赛要么
      的一个或多个字符的任意序列
    • [^\n]不是换行符,或
    • \n(?!\n)换行符但前提是不能再接再换行符

这种递归模式可以在任何长度适用于:

// useful function to quote strings for literal match in regular expressions 
RegExp.quote = RegExp.quote || function(str) { 
    return (str+"").replace(/(?=[.?*+^$[\]\\(){}|-])/g, "\\"); 
}; 
// helper function to build the above pattern recursively 
function buildRecursivePattern(chars, i) { 
    var c = RegExp.quote(chars[i]); 
    if (i < chars.length-1) return "(?:[^" + c + "]|" + c + buildRecursivePattern(chars, i+1) + ")"; 
    else return "(?!" + c + ")"; 
} 
function buildPattern(str) { 
    return RegExp(RegExp.quote(delimiter) + "|" + buildRecursivePattern(delimiter.match(/[^]/g), 0) + "+", "g"); 
} 

var str = 'hello world\n\nbye world\n\nfoo\nbar\n\nfoo\nbaz\n\n', 
    delimiter = "\n\n", 
    parts; 
parts = str.match(buildPattern(delimiter)) 

更新这里有一个String.prototype.split的修改应该添加包含匹配分隔符的功能:

if ("a".split(/(a)/).length !== 3) { 
    (function() { 
     var _f = String.prototype.split; 
     String.prototype.split = function(separator, limit) { 
      if (separator instanceof RegExp) { 
       var re = new RegExp(re.source, "g"+(re.ignoreCase?"i":"")+(re.multiline?"m":"")), 
        match, result = [], counter = 0, lastIndex = 0; 
       while ((match = re.exec(this)) !== null) { 
        result.push(this.substr(lastIndex, match.index-lastIndex)); 
        if (match.length > 1) result.push(match[1]); 
        lastIndex = match.index + match[0].length; 
        if (++counter === limit) break; 
       } 
       result.push(this.substr(lastIndex)); 
       return result; 
      } else { 
       return _f.apply(arguments); 
      } 
     } 
    })(); 
} 
+2

+ 1000你的正则表达式mojo是强大的,sensei。对于我们这些凡人来说,正则表达式的细分如何? – 2012-03-24 19:57:32

+0

应该将'buildPattern'中的'build()'调用改为'buildRecursivePattern'吗? – 2012-03-24 22:02:54