在javascript中通过正则表达式分割线?

时间:2014-07-16 11:09:58

标签: javascript regex

我有这种文字结构:

1.6.1 Members................................................................ 12
1.6.2 Accessibility.......................................................... 13
1.6.3 Type parameters........................................................ 13
1.6.4 The T generic type aka <T>............................................. 13

我需要创建JS对象:

{ 
  num:"1.6.1",
  txt:"Members"
},
{ 
  num:"1.6.2",
  txt:"Accessibility"
} ...

这不是问题。

问题在于我想通过积极前瞻的正则表达式分割提取值:

  

通过第一次时间拆分,您会看到下一个字符是字母

enter image description here

我尝试了什么:

'1.6.1 Members........... 12'.split(/\s(?=(?:[\w\. ])+$)/i)

这很好用:

["1.6.1", "Members...........", "12"] // I don't care about the 12.

但如果我有两个或更多的话:

'1.6.3 Type parameters................ 13'.split(/\s(?=(?:[\w\. ])+$)/i)

结果是:

["1.6.3", "Type", "parameters................", "13"] //再次,我不在乎13。

当然我可以加入他们,但我希望这些话能够在一起。

问题:

如何增强我的正则表达式而不是分裂单词?

期望的结果:

["1.6.3", "Type parameters"]

["1.6.3", "Type parameters........"] //我稍后会删除附加内容

["1.6.3", "Type parameters........13"] //我稍后会删除附加内容

NB

我知道我可以通过&#34; &#34;或者通过其他更简单的解决方案,但我寻求(纯粹的知识)增强我的解决方案使用积极的先行分割

Full online example :

nb2:

文本中间也可以包含大写字母。

3 个答案:

答案 0 :(得分:3)

您可以使用此正则表达式:

/^(\d+(?:\.\d+)*) (\w+(?: \w+)*)/gm

使用匹配的组#1和匹配的组#2获得所需的匹配。

Online Regex Demo

更新:对于String#split,您可以使用此正则表达式:

/ +(?=[A-Z\d])/g

Regex Demo

更新2:在更复杂的正则表达式之后,还可能在章节名称中使用大写字母:

var re = /(\D +(?=[a-z]))| +(?=[a-z\d])/gmi; 
var str = '1.6.3 Type Foo Bar........................................................ 13';
var m = str.split( re );
console.log(m[0], ',', m.slice(1, -1).join(''), ',', m.pop() );

//=> 1.6.3 , Type Foo Bar........................................................ , 13

答案 1 :(得分:2)

编辑:由于您已将1.6.1 The .net 4.5 framework....添加到要求中,我们可以调整答案:

^([\d.]+) ((?:[^.]|\.(?!\.))+)

如果你想在标题中允许最多三个点的序列,就像1.6.1 She said... Boo!...........一样,那么从那里({3}量词)可以轻松调整:

^([\d.]+) ((?:[^.]|\.(?!\.{3}))+)

原文:

^([\d.]+) ([^.]+)

regex demo中,请参阅右侧窗格中的“组”。

要检索第1组和第2组,例如:

var myregex = /^([\d.]+) ((?:[^.]|\.(?!\.))+)/mg;
var theMatchObject = myregex.exec(yourString);
while (theMatchObject != null) {
    // the numbers: theMatchObject[1]
    // the title: theMatchObject[1]
    theMatchObject = myregex.exec(yourString);
}

<强>输出

Group 1     Group 2
1.6.1       Members
1.6.2       Accessibility
1.6.3       Type parameters
1.6.4       The T generic type aka <T>**
1.6.1       The .net 4.5 framework

<强>解释

  • ^声称我们是行的开头
  • ([\d.]+)中的括号捕获第1组的数字和点
  • ((?:[^.]|\.(?!\.))+)中的括号捕获到第2组......
  • [^.]一个不是点的字符,|或......
  • \.(?!\.)一个没有点后跟的点......
  • +一次或多次

答案 2 :(得分:1)

您也可以使用此模式:

var myStr = "1.6.1 Members................................................................ 12\n1.6.2 Accessibility.......................................................... 13\n1.6.3 Type parameters........................................................ 13\n1.6.4 The T generic type aka <T>............................................. 13";

console.log(myStr.split(/ (.+?)\.{2,} ?\d+$\n?/m));

关于前瞻的方式:

我认为这是不可能的。因为跳过一个字符(这里是两个单词之间的空格)的唯一方法是在之前出现的空格(数字和第一个单词之间)匹配它。换句话说,您使用的字符不能匹配多次。

但是,如果除了要分割的空间外,所有模式都包含在前瞻中,并且由于前瞻中此子模式匹配的子字符串不是匹配结果的一部分(换句话说,它只是一个检查,相应的字符不会被正则表达式引擎吃掉),你不能跳过下一个空格,正则表达式引擎将继续他的路,直到下一个空格字符。