如何将特定字符串替换为另一个字符串



我从XML文件中读取了一些内容:

page_content = doc.xpath("/somenode/body").inner_text

此内容包含一些数据:

<p> Hello World, ""How are you today""
<a href=""www.hello.comm"">Hello</a>
etc.
</p>

如您所见,某些内容用两对双引号括起来。

我想要的结果是用一对双引号替换两对双引号:

<p> Hello World, "How are you today"
<a href="www.hello.comm">Hello</a>
etc.
</p>

我尝试的是:

page_content.gsub!(/[""]/, '"')
page_content.gsub!("""", '"')

这似乎不能完成这项工作。 关于如何获得预期结果的任何建议?

了解像Nokogiri这样的解析器是如何工作的是很重要的。

为了帮助您,它会尝试修复损坏/格式错误的 HTML 或 XML。您的HTML格式不正确,因此在Nokogiri解析它时将对其进行修复,但是,该过程可能会使Nokogiri进一步破坏HTML。为了避免这种情况,我们有时必须在将内容交给Nokogiri之前对其进行预处理,或者之后必须通过替换节点来解开它。

require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<p> Hello World, ""How are you today""
<a href=""www.hello.comm"">Hello</a>
etc.
</p>
EOT

这会将 HTML 解析为 DOM。

doc.at('p').to_html 
# => "<p> Hello World, ""How are you today""n<a href="" www.hello.comm>Hello</a>netc.n</p>"

处理文本""How are you today""时没有任何重整,因为它是一个文本节点:

doc.at('p').child.class # => Nokogiri::XML::Text
doc.at('p').child.content # => " Hello World, ""How are you today""n"

解析后很容易修复:

doc.at('p').child.content = doc.at('p').child.content.gsub('""', '"')
# => " Hello World, "How are you today"n"

尝试修复<a>标签的参数是完全不同的情况,因为到那时,Nokogiri 已经修复了双引号,导致标记错误:

doc.at('a').to_html
# => "<a href="" www.hello.comm>Hello</a>"

请注意,www.hello.comm已在其包含引号之外提升。

要解决此问题,需要在将HTML交给Nokogiri之前进行一些预处理,或者修复节点并用修复的节点替换损坏的节点。

以下是预处理<a>标记的基础:

html = <<EOT
<p> Hello World, ""How are you today""
<a href=""www.hello.comm"">Hello</a>
etc.
</p>
EOT
html.gsub(/href=""([^"]+)""/, 'href="1"')
# => "<p> Hello World, ""How are you today""n<a href="www.hello.comm">Hello</a>netc.n</p>n"

如果你走那条路,不要花哨。编写小的原子更改,以避免在 HTML 更改时破坏模式。

一个更健壮的方法(其中"健壮"比我们通常使用解析器得到的要少一些)是:

bad_a = doc.at('a')
fixed_a = bad_a.to_html.gsub(/""s([^>]+)>/, '"1">')
bad_a.replace(fixed_a)
doc.at('p')
# => #(Element:0x3fe4ce9de9e4 {
#      name = "p",
#      children = [
#        #(Text " Hello World, "How are you today"n"),
#        #(Element:0x3fe4ce9e0fdc {
#          name = "a",
#          attributes = [
#            #(Attr:0x3fe4ce9e0fa0 {
#              name = "href",
#              value = "www.hello.comm"
#              })],
#          children = [ #(Text "Hello")]
#          }),
#        #(Text "netc.n")]
#      })
doc.at('p').to_html
# => "<p> Hello World, "How are you today"n<a href="www.hello.comm">Hello</a>netc.n</p>"
可以使用

毯子gsub来按摩文本,但这在大型/复杂文档中具有很高的附带损害风险。想象一下,如果文档会发生什么情况,如果

html.gsub('""', '"')

当有许多标签包含空字符串时使用,例如:

<input value="" name="foo"><input value="" name="bar">

搜索/替换的结果将是:

<input value=" name="foo"><input value=" name="bar">

这几乎不会改善事情,相反,它会进一步严重破坏文档。

相反,最好通过手术解决问题。回到黑暗的、早期的、网络先驱的日子里,我们曾经看到大量畸形的内容,不得不用正则表达式处理它是正常的攻击计划。现在,使用解析器,我们通常可以避免它,并且可以隔离问题并有选择地修复我们想要的内容。查看这样做所需的代码表明,正确完成它并不需要很多。

page_content.gsub!('""', '"')
page_content.gsub!(/"{2}/, '"')

rubular.com

a='<p> Hello World, ""How are you today""
<a href=""www.hello.comm"">Hello</a>
etc.
</p>'
a.gsub! '""', '"'
[19] pry(main)> puts a
<p> Hello World, "How are you today"
<a href="www.hello.comm">Hello</a>
etc.
</p>

相关内容

  • 没有找到相关文章

最新更新