2009-10-19 16 views
0

我有這樣如何除去最後[d +]以外的所有[d +]?

/root/children[2]/header[1]/something/some[4]/table/tr[1]/links/a/b 

/root/children[2]/header[1]/something/some[4]/table/tr[2] 

字符串我怎樣才能重現繩子,讓所有/\[\d+\]/除了最後/\[\d+\]/被刪除?

所以我應該結束了。

/root/children/header/something/some/table/tr[1]/links/a/b 

/root/children/header/something/some/table/tr[2] 

回答

2

沒有循環爲您服務。使用前向斷言(= ...?):

s.gsub(/\[\d+\](?=.*\[)/, "") 

有非常有用的環視運營商的合理解釋here

+1

正好。您在輸入相同解決方案時發佈了此內容,除非您在「」之前放置了有用的空間! – 2009-10-20 00:04:43

+1

哦,我做了速度檢查,這個版本幾乎是Pavel的while循環的兩倍... – 2009-10-20 00:05:50

+0

不錯的一個Glenn。這是一個重要的空間,一個= P。 – 2009-10-20 00:54:53

1

我們將不得不使用while循環,我猜。這裏有很好的C型循環解決方案:

while s.gsub!(/(\[\d+\])(.*?)(\[\d+\])/, '\2\3'); end 

這有點難以閱讀,所以我會解釋一下。我們的想法是,我們將字符串與需要兩個[\d+]塊的模式匹配以保留字符串。在替換中,我們只是刪除第一個。我們重複它直到字符串不匹配(所以它只包含一個這樣的塊),並利用當字符串不匹配時gsub!不執行替換的事實。

+1

清潔劑,以及約5 % 更快。 +1 – 2009-10-19 22:27:36

+0

只要不要忘記對那隻小狗發表評論。 – 2009-10-19 22:41:14

+0

查看Charles Dale的更好回答... – 2009-10-20 00:06:37

0

我絕對肯定有一個更好的解決方案,但是這應該讓你去:

string = "/root/children[2]/header[1]/something/some[4]/table/tr[1]/links/a/b" 
count = string.scan(/\[\d+\]/).size 
index = 0 
string.gsub(/\[\d+\]/) do |capture| 
    index += 1 
    index == count ? capture : "" 
end 
0

試試這個:

str.scan(/\[\d+\]/)[0..-2].each {|match| str.sub!(match, '')} 
比我
相關問題