Lookbehind和lookahead正则表达式

时间:2012-10-08 20:30:04

标签: ruby regex

我有这样的字符串:

  

journals / cl / SantoNR90 ::: Michele Di Santo :: Libero Nigro :: Wilma   Russo ::: Modula-2中程序员定义的控制抽象

我需要捕获Michele Di SantoLibero NigroWilma Russo,但不是最后一个。

这个正则表达式几乎符合我的需要:

/(?<=::).*?(?=::)/

但它有问题,它捕获第三个结肠

str.scan(/(?<=::).*?(?=::)/) #=> [":Michele Di Santo", ...]

如您所见,第一场比赛开头有一个冒号。

如何修复此正则表达式以避免出现第三个冒号?

3 个答案:

答案 0 :(得分:7)

不要使用正则表达式。您需要做的就是将输入字符串拆分为:::,从结果数组中取出第二个字符串,然后将其拆分为::。与正则表达式版本相比,代码更快,运行更​​快,更易于阅读。

编辑:代码:

str.split(':::')[1].split('::')

在CodePad上运行:http://codepad.org/1BNNwoh6

答案 1 :(得分:3)

这样做的表达式可能是:

(?<=::)[^:].*?(?=::)

虽然如果要搜索的字符串总是以“xxx ::: A :: B :: C ::: xxx”的形式,并且您只关心A,B和C,请考虑使用更具体的内容,并使用捕获组获得A,B和C:

:::(.+?)::(.+?)::(.+?):::

$1$2$3将包含小组匹配。

答案 2 :(得分:0)

我使用简单的split因为字符串基本上是带冒号而不是逗号的CSV:

str = 'journals/cl/SantoNR90:::Michele Di Santo::Libero Nigro::Wilma Russo:::Programmer-Defined Control Abstractions in Modula-2'
items = split(':')
str1, str2, str3 = items[3], items[5], items[7]

=> [
      [0] "Michele Di Santo",
      [1] "Libero Nigro",
      [2] "Wilma Russo"
  ]

你也可以使用:

str1, str2, str3 = str.split(':').select{ |s| s > '' }[1, 3]

如果可以引用冒号,请使用CSV模块并将字段分隔符设置为“:”。