除了最后一个[d +]之外,如何删除所有[d +]?

时间:2009-10-19 22:01:27

标签: ruby regex

我有一个像

这样的字符串
/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]

4 个答案:

答案 0 :(得分:2)

没有循环给你。使用先行断言(?= ...):

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

对非常有用的环视操作符here

有一个合理的解释

答案 1 :(得分:1)

我猜我们必须使用while循环。这里有很好的'C风格循环解决方案:

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

这有点难以阅读,所以我会解释。我们的想法是,我们将字符串与需要两个 [\d+]块的模式匹配,以便在字符串中保留。在替换中,我们只删除第一个。我们重复它直到字符串不匹配(因此它只包含一个这样的块)并利用gsub!在字符串不匹配时不执行替换的事实。

答案 2 :(得分: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

答案 3 :(得分:0)

试试这个:

str.scan(/\[\d+\]/)[0..-2].each {|match| str.sub!(match, '')}