2012-08-25 15 views
1

在建設類似如何知道是否匹配是相鄰到以前的比賽

string.scan(regex){...} 

string.gsub(regex){...} 

如何檢查是否匹配爲一個循環週期是相鄰的上一個在原來的字符串?例如,在

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

將有三場比賽"ab""aab""aaab"。在每個循環期間,我希望他們有可變continuedfalsetrue,並false分別因爲"ab"是第一匹配週期,"aab"是與其相鄰的,並"c"下一場比賽"aaab"之前中斷。

"ab" #=> continued = false 
"aab" #=> continued = true 
"aaab" #=> continued = false 

原始動物中是否有一個錨點引用了前一個匹配位置的結尾?如果是這樣,那麼可以在正則表達式中使用。如果沒有,我可能需要使用諸如MatchData#offset之類的東西。並在循環中做一些計算。

順便說一句,在origuruma正則表達式中是什麼\G?我的印象是它可能是我想要的錨,但我不確定它是什麼。

+0

不幸的是,'scan'和'gsub'都不能與MatchData對象一起使用。你可以編寫你自己的'scan',它很容易實現,只需使用'match'和它的偏移量支持。 –

+2

@ muistooshort''〜'和'$〜.offset'可以在'scan'中使用。例如''aaaaaaaaaa「.scan(/./){| x | p $〜.offset(0)}'很好。 – sawa

+0

謝謝,我從來沒有能夠記住所有的魔法全局。我仍然認爲如果'scan'給你一個MatchData會更好,命名捕獲組有點不方便。 PS:http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt,我不知道這是最新的參考,但這是我書籤。 –

回答

1

我不認爲使用這些方法可獲得偏移數據。您可能不得不使用Regexp#match,每次都沿着位置傳遞。返回的MatchData對象包含您需要做任何替換等的所有信息。

當然,如果增加偏移量並進行字符串替換,如果替換長度與匹配長度不一致,則必須小心。這裏常見的模式是將字符串向後走,但我認爲您不能使用這些方法跟蹤該模式,因此您需要調整偏移量。

編輯|實際上,如果你在完全單獨的步驟中進行更換,你將能夠向後走繩。首先找到您需要更換的所有零件以及偏移量。接下來,按相反的順序迭代該列表,進行替換。

+1

你可以使用'match'來創建一個'scan',它比標準掃描更有意義,因爲它將一個MatchData而不是一個簡單的數組作爲一個MatchData,我可以用命名捕獲組。 –

+1

'scan'可以使用'$〜'和'$〜.offset'。例如''aaaaaaaaaa「.scan(/./){| x | p $〜.offset(0)}'很好。 – sawa

+0

@sawa哇,我不知道。好找! :) – d11wtq

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 

所以,你可以再只保留最後的匹配和位置的長度的軌道和做數學題看看他們是否相鄰。

相關問題