Ruby:如何基于给定的正则表达式附加到字符串的每一行?

时间:2013-08-23 21:46:11

标签: ruby regex

我想将</tag>附加到缺少它的每一行:

text = '<tag>line 1</tag>
        <tag>line2         # no closing tag, append
        <tag>line3         # no closing tag, append
             line4</tag>   # no opening tag, but has a closing tag, so ignore
        <tag>line5</tag>'

我试图创建一个正则表达式来匹配这个,但我知道它错了:

text.gsub! /.*?(<\/tag>)Z/, '</tag>'

如何创建正则表达式以有条件地附加每一行?

4 个答案:

答案 0 :(得分:2)

你走了:

text.gsub!(%r{(?<!</tag>)$}, "</tag>")

说明:

$表示行尾,\z表示字符串结尾。 \Z意味着类似的东西,并发症。

(?<!)共同努力创造一种消极的外观。

答案 1 :(得分:0)

鉴于提供的示例,我只是做这样的事情:

text.split(/<\/?tag>/).
     reject {|t| t.strip.length == 0 }.
     map {|t| "<tag>%s</tag>" % t.strip }.
     join("\n")

你基本上把它们当作记录分隔符,所以你可以拆分它们,拒绝任何空白记录,然后从提取的值中构造一个新的组合字符串。当你不能指望新行是记录分隔符并且通常可以容忍缺少标记时,这很有效。

如果您坚持使用纯正则表达式解决方案,并且您的数据格式总是匹配给定格式(每行一条记录),您可以使用负面的lookbehind:

text.strip.gsub(/(?<!<\/tag>)(\n|$)/, "</tag>\\1")

答案 2 :(得分:0)

可行的方法是:

/<tag>[^\n ]+[^>][\s]*(\n)/

这将返回没有“&gt;”的所有换行符在他们面前。

将其替换为“\ n”,即

text.gsub!( /<tag>[^\n ]+[^>][\s]*(\n)/ , "</tag>\n")

要进行更多抛光,请尝试http://rubular.com/

答案 3 :(得分:0)

text = '<tag>line 1</tag>
        <tag>line2        
        <tag>line3
        line4</tag>
        <tag>line5</tag>'

result = ""

text.each_line do |line|
  line.rstrip!
  line << "</tag>" if not line.end_with?("</tag>")
  result << line << "\n"
end

puts result

--output:--
<tag>line 1</tag>
        <tag>line2</tag>
        <tag>line3</tag>
        line4</tag>
        <tag>line5</tag>