如何知道匹配是否与上一场比赛相邻

时间:2012-08-25 04:04:21

标签: ruby regex ruby-1.9.3 oniguruma

在像

这样的建筑中
string.scan(regex){...}

string.gsub(regex){...}

如何检查循环周期的匹配是否与原始字符串中的前一个匹配?例如,在

"abaabcaaab".scan(/a+b/){|match|
    ...
    continued = ...
    ...
}

将有三个匹配"ab""aab""aaab"。在每个周期中,我希望它们分别使变量continuedfalsetruefalse,因为"ab"是第一个匹配周期,{ {1}}与其相邻,"aab"在下一场比赛"c"之前中断。

"aaab"

在origuruma中是否有一个锚点指的是前一个匹配位置的结尾?如果是这样,那可以在正则表达式中使用。如果没有,我可能需要使用像"ab" #=> continued = false "aab" #=> continued = true "aaab" #=> continued = false 这样的东西。并在循环中做一些计算。

顺便说一下,origuruma正则表达式中MatchData#offset是什么?我的印象是它可能是我想要的锚,但我不确定它是什么。

2 个答案:

答案 0 :(得分:1)

我不相信使用这些方法可以获得偏移数据。您可能必须使用Regexp#match,每次都会传递该位置。返回的MatchData对象包含进行任何替换等所需的所有信息。

当然,如果替换的长度与字符串替换相结合,如果替换的长度与匹配的长度不同,则必须要小心。这里常见的模式是向后移动字符串,但我不认为您可以使用这些方法遵循该模式,因此您需要调整偏移量。

编辑|实际上,如果你在一个完全独立的步骤中进行替换,你可以向后走绳子。首先找到您需要更换的所有内容以及偏移量。接下来,以相反的顺序迭代该列表,进行替换。

答案 1 :(得分:1)

StringScanner非常适合这项任务:http://corelib.rubyonrails.org/classes/StringScanner.html

require 'strscan'
s = StringScanner.new('abaabcaaab')

begin
        puts s.pos
        s.scan_until(/a+b/)
        puts s.matched
end while !s.matched.nil?

输出

0
ab
2
aab
5
aaab
10
nil

因此,您可以跟踪最后一场比赛的长度和位置,并进行数学计算以确定它们是否相邻。