2012-08-17 37 views
63

我有一个字符串:Javascript和正则表达式:拆分字符串,并保持分离

var string = "aaaaaa<br />&dagger; bbbb<br />&Dagger; cccc" 

而且我想在此字符串后跟一个特殊字符分隔符<br />分裂。

为了做到这一点,我用这:

string.split(/<br \/>&#?[a-zA-Z0-9]+;/g); 

我得到我所需要的,但我失去的分隔符。 以下是示例:http://jsfiddle.net/JwrZ6/1/

如何保留分隔符?

+0

如果你知道的分隔符事前,为什么不只是做...'VAR DELIM = “
”;'? – 2012-08-17 07:59:23

+0

谢谢@SiGanteng,我知道预定义的分隔符,但我无法为我的例子工作。我需要保持分隔符为
,后面跟着特殊字符,因为有时候我可以有一个
,后面跟着特殊字符,这个字符不必被分割。 – 2012-08-17 08:02:45

+1

好问题,我有一个类似的情况,知道分隔符没有帮助。我正在分裂“]和[”。所以实际上我的分隔符是“&”,但是分割并不够精确,我需要使用括号来确定正确的分割。不过,我需要将这些括号放回我的拆分字符串中。每一侧各有1个。 – PandaWood 2014-10-23 00:44:12

回答

55

使用positive lookahead使正则表达式断言特殊字符存在,但实际上并没有与之相匹配的:

string.split(/<br \/>(?=&#?[a-zA-Z0-9]+;)/g); 

See it in action

更新:固定错字(移动字面;先行括号内)

+0

非常感谢Jon,这解决了我的问题。 – 2012-08-17 08:04:15

29

如果换定界符括号这将是返回数组的一部分。

string.split(/(<br \/>&#?[a-zA-Z0-9]+);/g); 
// returns ["aaaaaa", "<br />&dagger;", "bbbb", "<br />&Dagger;", "cccc"] 

根据你要保持变化,这其中的亚组部分你匹配

string.split(/(<br \/>)&#?[a-zA-Z0-9]+;/g); 
// returns ["aaaaaa", "<br />", "bbbb", "<br />", "cccc"] 

你可以通过忽略字母的大小写 string.split(/()&#提高表达?[一个-Z0-9] +;/GI);

而且您可以匹配预定义的组,例如:\d等于[0-9]\w等于[a-zA-Z0-9_]。这意味着你的表情可能看起来像这样。

string.split(/<br \/>(&#?[a-z\d]+;)/gi); 

有一个好的Regular Expression Reference on JavaScriptKit

+2

更好的是,我不知道我们只能保留分隔符的一部分。事实上,我只需要保留特殊的字符,我可以这样做:string.split(/
(&#?[a-zA-Z0-9] +;)/ g); – 2012-08-17 08:16:06

+1

您可以通过忽略单词的情况来优化表情。或匹配预定义的字符类。我会更新我的答案。 – 2012-08-17 08:44:15

+1

正是我在找什么....谢谢.. ..! – 2014-11-13 06:53:33

0

扩展函数使用子字符串或RegEx分割字符串,并根据第二个参数提前或落后分隔符。

String.prototype.splitKeep = function (splitter, ahead) { 
     var self = this; 
     var result = []; 
     if (splitter != '') { 
      var matches = []; 
      // Getting mached value and its index 
      var replaceName = splitter instanceof RegExp ? "replace" : "replaceAll"; 
      var r = self[replaceName](splitter, function (m, i, e) { 
       matches.push({ value: m, index: i }); 
       return getSubst(m); 
      }); 
      // Finds split substrings 
      var lastIndex = 0; 
      for (var i = 0; i < matches.length; i++) { 
       var m = matches[i]; 
       var nextIndex = ahead == true ? m.index : m.index + m.value.length; 
       if (nextIndex != lastIndex) { 
        var part = self.substring(lastIndex, nextIndex); 
        result.push(part); 
        lastIndex = nextIndex; 
       } 
      }; 
      if (lastIndex < self.length) { 
       var part = self.substring(lastIndex, self.length); 
       result.push(part); 
      }; 
      // Substitution of matched string 
      function getSubst(value) { 
       var substChar = value[0] == '0' ? '1' : '0'; 
       var subst = ''; 
       for (var i = 0; i < value.length; i++) { 
        subst += substChar; 
       } 
       return subst; 
      }; 
     } 
     else { 
      result.add(self); 
     }; 
     return result; 
    }; 

测试:

test('splitKeep', function() { 
     // String 
     deepEqual("1231451".splitKeep('1'), ["1", "231", "451"]); 
     deepEqual("123145".splitKeep('1', true), ["123", "145"]); 
     deepEqual("1231451".splitKeep('1', true), ["123", "145", "1"]); 
     deepEqual("hello man how are you!".splitKeep(' '), ["hello ", "man ", "how ", "are ", "you!"]); 
     deepEqual("hello man how are you!".splitKeep(' ', true), ["hello", " man", " how", " are", " you!"]); 
     // Regex 
     deepEqual("mhellommhellommmhello".splitKeep(/m+/g), ["m", "hellomm", "hellommm", "hello"]); 
     deepEqual("mhellommhellommmhello".splitKeep(/m+/g, true), ["mhello", "mmhello", "mmmhello"]); 
    }); 
85

我有相似,但略有不同的问题。无论如何,下面是三种不同场景的示例,说明在哪里保留删除者。

"1、2、3".split("、") == ["1", "2", "3"] 
"1、2、3".split(/(、)/g) == ["1", "、", "2", "、", "3"] 
"1、2、3".split(/(?=、)/g) == ["1", "、2", "、3"] 
"1、2、3".split(/(?!、)/g) == ["1、", "2、", "3"] 
"1、2、3".split(/(.*?、)/g) == ["", "1、", "", "2、", "3"] 

警告:第四只会工作分割单个字符。ConnorsFan礼物an alternative

// Split a path, but keep the slashes that follow directories 
var str = 'Animation/rawr/javascript.js'; 
var tokens = str.match(/[^\/]+\/?|\//g); 
+1

非常好的东西m8,谢谢! – 2015-08-07 21:38:26

+1

优秀的答案! – 2015-08-27 17:39:52

+1

你救了我的一天:) – noviewpoint 2016-02-13 13:05:18

0

我一直在使用这样的:

String.prototype.splitBy = function (delimiter) { 
    var 
    delimiterPATTERN = '(' + delimiter + ')', 
    delimiterRE = new RegExp(delimiterPATTERN, 'g'); 

    return this.split(delimiterRE).reduce((chunks, item) => { 
    if (item.match(delimiterRE)){ 
     chunks.push(item) 
    } else { 
     chunks[chunks.length - 1] += item 
    }; 
    return chunks 
    }, []) 
} 

除此之外,你不应该惹String.prototype,所以这里是一个函数的版本:

var splitBy = function (text, delimiter) { 
    var 
    delimiterPATTERN = '(' + delimiter + ')', 
    delimiterRE = new RegExp(delimiterPATTERN, 'g'); 

    return text.split(delimiterRE).reduce(function(chunks, item){ 
    if (item.match(delimiterRE)){ 
     chunks.push(item) 
    } else { 
     chunks[chunks.length - 1] += item 
    }; 
    return chunks 
    }, []) 
} 

所以你可以这样做:

var haystack = "aaaaaa<br />&dagger; bbbb<br />&Dagger; cccc" 
var needle = '<br \/>&#?[a-zA-Z0-9]+;'; 
var result = splitBy(string, haystack) 
console.log(JSON.stringify(result, null, 2)) 

你会结了:

[ 
    "<br />&dagger; bbbb", 
    "<br />&Dagger; cccc" 
] 
3

回答在这里也JavaScript Split Regular Expression keep the delimiter

使用先行模式的正则表达式 例如

var string = '500x500-11*90~1+1'; 
string = string.replace(/(?=[$-/:-?{-~!"^_`\[\]])/gi, ","); 
string = string.split(","); 

这一意志(=模式?)给你以下结果。

[ '500x500', '-11', '*90', '~1', '+1' ] 

也可直接拆分

string = string.split(/(?=[$-/:-?{-~!"^_`\[\]])/gi); 

给予同样的结果

[ '500x500', '-11', '*90', '~1', '+1' ] 
+0

为什么不立即拆分,就像乔恩接受的答案一样? – Gordon 2016-12-30 21:21:19

+0

@Gordon ... :)我可以这样做......更新代码...干杯 – Fry 2017-01-03 12:06:58

0
function formatDate(dt, format) { 
    var monthNames = [ 
     "Enero", "Febrero", "Marzo", 
     "Abril", "Mayo", "Junio", "Julio", 
     "Agosto", "Setiembre", "Octubre", 
     "Noviembre", "Diciembre" 
    ]; 
    var Days = [ 
     "Domingo", "Lunes", "Martes", "Miercoles", 
     "Jueves", "Viernes", "Sabado" 
    ]; 

    function pad(n, width, z) { 
     z = z || '0'; 
     n = n + ''; 
     return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n; 
    } 

    function replace(val, date) { 
     switch (val) { 
      case 'yyyy': 
       return date.getFullYear(); 
      case 'YYYY': 
       return date.getFullYear(); 
      case 'yy': 
       return (date.getFullYear() + "").substring(2); 
      case 'YY': 
       return (date.getFullYear() + "").substring(2); 
      case 'MMMM': 
       return monthNames[date.getMonth()]; 
      case 'MMM': 
       return monthNames[date.getMonth()].substring(0, 3); 
      case 'MM': 
       return pad(date.getMonth() + 1, 2); 
      case 'M': 
       return date.getMonth() + 1; 
      case 'dd': 
       return pad(date.getDate(), 2); 
      case 'd': 
       return date.getDate(); 
      case 'DD': 
       return Days[date.getDay()]; 
      case 'D': 
       return Days[date.getDay()].substring(0, 3); 
      case 'HH': 
       return pad(date.getHours(), 2); 
      case 'H': 
       return date.getHours(); 
      case 'mm': 
       return pad(date.getMinutes(), 2); 
      case 'm': 
       return date.getMinutes(); 
      case 'ss': 
       return pad(date.getSeconds(), 2); 
      case 's': 
       return date.getSeconds(); 
      default: 
       return val; 
     } 
    } 

    var ds = format.split(/(|,|:)/g); 
    var newFormat = ''; 
    for (var i = 0; i < ds.length; i++) { 
     newFormat += replace(ds[i], dt); 
    } 
    return newFormat; 
} 

var a = "2016-08-22T16:02:05.645Z"; 
var d = new Date(Date.parse(a)); 
// var d = new Date(); 
console.log(formatDate(d, 'd de MMMM, de YYYY H:mm'));