在标签之间删除并在`gsub`中使用正则表达式中的变量

时间:2015-10-07 23:28:45

标签: ruby regex

我的@outbound_text看起来像这样:

<CREATE-EVENT>\n\t\t\t\t<COLLECTION>PAM</COLLECTION>\n\t\t\t\t<EVENT-TYPE>survey_answer</EVENT-TYPE>\n\t\t\t\t<JSON-STRING>\n\t\t\t\t\t{\n\t\t\t\t\t question1:done,\n\t\t\t\t\t question2:done,\n\t\t\t\t\t question3:done,\n\t\t\t\t\t question4:done,\n\t\t\t\t\t question5:done,\n\t\t\t\t\t question6:done\n\t\t\t\t\t}\n\t\t\t\t</JSON-STRING>\n\t\t\t</CREATE-EVENT>\n\n\t\t\t\n      <EMAIL>\n        <ADDRESS>bot_client_id</ADDRESS>\n        <SUBJECT>PAM responses for Wednesday October 07</SUBJECT>\n        <BODY>\nHi, there

我想删除<CREATE-EVENT></CREATE-EVENT>之间的所有内容。

我尝试了以下内容,其中tag"CREATE-EVENT"

open_tag = "<" + tag + ">"
close_tag = "</" + tag + ">"
@outbound_text.gsub!(/#{open_tag}/(.*)\/#{close_tag}/, '')

3 个答案:

答案 0 :(得分:4)

以下是正则表达式的变量替换:

/#{open_tag}.*#{close_tag}/, ...

假设正则表达式的开头/和结束/是双引号并且有。

以下是一个完整的例子:

tag = 'CREATE-EVENT'

open_tag = "<#{tag}>"
close_tag = "</#{tag}>"
any_text = ".*"

html_tag = /#{open_tag} 
            #{any_text}
            #{close_tag}/xm

@outbound_text = %q{
hello
 <CREATE-EVENT>
        <COLLECTION>PAM</COLLECTION>
        <EVENT-TYPE>
</CREATE-EVENT>
world
}

p @outbound_text.gsub!(html_tag, '')

--output:--
"\nhello\n \nworld\n"

答案 1 :(得分:1)

在处理XML或HTML时,不要使用正则表达式,除非标记非常简单并且您拥有生成它的任务。通过对传入数据进行少量更改,您的代码可能会中断的几率非常高。阅读“Match All Occurrences of a Regex”,试图解释使用模式解析XML和HTML的问题。

相反,使用更具弹性的解析器。我就是这样做的:

POST

您的XML示例在语法上不正确,因为它缺少根节点并且具有未终止的xml = <<EOT <CREATE-EVENT> <COLLECTION>PAM</COLLECTION> <EVENT-TYPE>survey_answer</EVENT-TYPE> <JSON-STRING> { question1:done, question2:done, question3:done, question4:done, question5:done, question6:done } </JSON-STRING> </CREATE-EVENT> <EMAIL> <ADDRESS>bot_client_id</ADDRESS> <SUBJECT>PAM responses for Wednesday October 07</SUBJECT> <BODY/> </EMAIL> EOT require 'nokogiri' doc = Nokogiri::XML::DocumentFragment.parse('<root>' + xml + '</root>') 节点,所以我在解析时添加了<EMAIL>并用</EMAIL>包裹xml 。在现实生活中,您将传递整个XML字符串,假设它是有效的XML,使用:

<root>

一旦将其解析为DOM,我就可以使用:

doc = Nokogiri::XML(xml)

删除doc.at('CREATE-EVENT').children.remove 的子节点,导致:

<CREATE-EVENT>

此时puts doc.to_xml # >> <root><CREATE-EVENT/> # >> <EMAIL> # >> <ADDRESS>bot_client_id</ADDRESS> # >> <SUBJECT>PAM responses for Wednesday October 07</SUBJECT> # >> <BODY/> # >> </EMAIL> # >> </root> 现在为空。

如果您想将某些内容替换为该节点,则同样容易:

<CREATE-EVENT/>

导致:

word = 'bar'
doc.at('CREATE-EVENT').children = "<foo>#{ word }</foo>"

我很少会使用# >> <root><CREATE-EVENT><foo>bar</foo></CREATE-EVENT> # >> <EMAIL> # >> <ADDRESS>bot_client_id</ADDRESS> # >> <SUBJECT>PAM responses for Wednesday October 07</SUBJECT> # >> <BODY/> # >> </EMAIL> # >> </root> sub来更改HTML或XML。相反,我先抓住一个解析器。它可能不会那么快,但它是一个更强大的解决方案,这意味着能够更频繁地在夜间睡觉。

您可以通过搜索Stack Overflow(Nokogiri)或互联网来详细了解如何使用

答案 2 :(得分:-1)

@outbound_text.gsub(/<CREATE-EVENT>(.*)<\/CREATE-EVENT>/m, '\1')
  #=> "\n\t\t\t\t<COLLECTION>PAM</COLLECTION>\n\t\t\t\t<EVENT-TYPE>
  #    survey_answer</EVENT-TYPE>\n\t\t\t\t<JSON-STRING>\n\t\t\t\t\t
  #    {\n\t\t\t\t\t question1:done,\n\t\t\t\t\t question2:done,
  #    \n\t\t\t\t\t question3:done,\n\t\t\t\t\t question4:done,
  #    \n\t\t\t\t\t question5:done,\n\t\t\t\t\t question6:done
  #    \n\t\t\t\t\t}\n\t\t\t\t</JSON-STRING>\n\t\t\t\n\n\t\t\t\n      <EMAIL>\n
  #        <ADDRESS>bot_client_id</ADDRESS>\n        <SUBJECT>PAM
  #    responses for Wednesday October 07</SUBJECT>\n        <BODY>\nHi, there" 

我已经打破了返回字符串,因此可以更容易地看到它。问题是您在正则表达式的末尾忘记了/m(多行)。