我在MySQL列中有一个包含HTML的文本blob字段。我必须改变一些标记,所以我想我会用ruby脚本来做。 Ruby在这里无关紧要,但是看到它的答案会很高兴。标记如下所示:
<h5>foo</h5>
<table>
<tbody>
</tbody>
</table>
<h5>bar</h5>
<table>
<tbody>
</tbody>
</table>
<h5>meow</h5>
<table>
<tbody>
</tbody>
</table>
我需要将每个文本的第一个<h5>foo</h5>
块更改为<h2>something_else</h2>
,同时保留字符串的其余部分。
使用Ruby似乎无法获得正确的PCRE正则表达式。
答案 0 :(得分:31)
# The regex literal syntax using %r{...} allows / in your regex without escaping
new_str = my_str.sub( %r{<h5>[^<]+</h5>}, '<h2>something_else</h2>' )
使用String#sub
代替String#gsub
只会导致第一次替换。如果你需要动态选择'foo'是什么,你可以在正则表达式文字中使用字符串插值:
new_str = my_str.sub( %r{<h5>#{searchstr}</h5>}, "<h2>#{replacestr}</h2>" )
然后,如果你知道'foo'是什么,你不需要正则表达式:
new_str = my_str.sub( "<h5>searchstr</h5>", "<h2>#{replacestr}</h2>" )
甚至:
my_str[ "<h5>searchstr</h5>" ] = "<h2>#{replacestr}</h2>"
如果您需要运行代码来找出替换,您可以使用sub的块形式:
new_str = my_str.sub %r{<h5>([^<]+)</h5>} do |full_match|
# The expression returned from this block will be used as the replacement string
# $1 will be the matched content between the h5 tags.
"<h2>#{replacestr}</h2>"
end
答案 1 :(得分:6)
每当我必须解析或修改HTML或XML时,我都会找到解析器。我几乎从不打扰正则表达式或instring,除非它绝对是一个明智的选择。
以下是使用Nokogiri的方法,没有任何正则表达式:
text = <<EOT
<h5>foo</h5>
<table>
<tbody>
</tbody>
</table>
<h5>bar</h5>
<table>
<tbody>
</tbody>
</table>
<h5>meow</h5>
<table>
<tbody>
</tbody>
</table>
EOT
require 'nokogiri'
fragment = Nokogiri::HTML::DocumentFragment.parse(text)
print fragment.to_html
fragment.css('h5').select{ |n| n.text == 'foo' }.each do |n|
n.name = 'h2'
n.content = 'something_else'
end
print fragment.to_html
解析之后,这就是Nokogiri从片段中返回的内容:
# >> <h5>foo</h5>
# >> <table><tbody></tbody></table><h5>bar</h5>
# >> <table><tbody></tbody></table><h5>meow</h5>
# >> <table><tbody></tbody></table>
这是在运行之后:
# >> <h2>something_else</h2>
# >> <table><tbody></tbody></table><h5>bar</h5>
# >> <table><tbody></tbody></table><h5>meow</h5>
# >> <table><tbody></tbody></table>
答案 2 :(得分:2)
将String.gsub与正则表达式<h5>[^<]+<\/h5>
:
>> current = "<h5>foo</h5>\n <table>\n <tbody>\n </tbody>\n </table>"
>> updated = current.gsub(/<h5>[^<]+<\/h5>/){"<h2>something_else</h2>"}
=> "<h2>something_else</h2>\n <table>\n <tbody>\n </tbody>\n </table>"
注意,您可以舒适地测试ruby正则表达式in your browser。