我有这样的字符串:
journals / cl / SantoNR90 ::: Michele Di Santo :: Libero Nigro :: Wilma Russo ::: Modula-2中程序员定义的控制抽象
我需要捕获Michele Di Santo
,Libero Nigro
,Wilma Russo
,但不是最后一个。
这个正则表达式几乎符合我的需要:
/(?<=::).*?(?=::)/
但它有问题,它捕获第三个结肠
str.scan(/(?<=::).*?(?=::)/) #=> [":Michele Di Santo", ...]
如您所见,第一场比赛开头有一个冒号。
如何修复此正则表达式以避免出现第三个冒号?
答案 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模块并将字段分隔符设置为“:”。