我有以下字符串,我想删除包含标记本身的<EMAIL>
标记之间的所有内容:
"Great, I will send you something at 888@gmail.com.\n <EMAIL><ADDRESS>T888@gmail.com</ADDRESS><SUBJECT>Quick note on 888@gmail.com</SUBJECT>\n <BODY>Hi, just dropping you a quick note.</BODY></EMAIL>"
我使用以下内容删除它:
string = string.gsub(/<EMAIL>(.*)<\/EMAIL>/, '').strip
它不起作用。
当我从字符串中删除\n
时(我不愿意,因为它会使格式化和输入更具限制性),然后我得到以下内容:
=> "Great, I will send you something at 888@gmail.com."
换句话说,当我删除它时它会起作用。
如何更改我的gsub语句以适应\ n以及为什么会导致失败?
答案 0 :(得分:7)
您的字符串是多行的,但默认情况下,Ruby regexp逐行工作,因此<EMAIL>
和</EMAIL>
位于两个不同的行上,正则表达式永远不会匹配。
这是因为在默认模式下,元字符.
代表除换行符之外的任何字符。
您需要使用m
(多行)标记:
s= "Great, I will send you something at 888@gmail.com.\n <EMAIL><ADDRESS>T888@gmail.com</ADDRESS><SUBJECT>Quick note on 888@gmail.com</SUBJECT>\n <BODY>Hi, just dropping you a quick note.</BODY></EMAIL>"=> "Great, I will send you something at 888@gmail.com.\n <EMAIL><ADDRESS>T888@gmail.com</ADDRESS><SUBJECT>Quick note on 888@gmail.com</SUBJECT>\n <BODY>Hi, just dropping you a quick note.</BODY></EMAIL>"
s.gsub(/<EMAIL>(.*)<\/EMAIL>/m, '').strip
返回:
"Great, I will send you something at 888@gmail.com."
答案 1 :(得分:2)
您正在做什么 可以工作,但它非常脆弱,因此不建议使用。 相反,请使用Nokogiri之类的解析器:
require 'nokogiri'
str = "Great, I will send you something at 888@gmail.com.\n <EMAIL><ADDRESS>T888@gmail.com</ADDRESS><SUBJECT>Quick note on 888@gmail.com</SUBJECT>\n <BODY>Hi, just dropping you a quick note.</BODY></EMAIL>"
以下是解析文档的方法:
doc = Nokogiri::XML::DocumentFragment.parse(str)
如果字符串是有效的XML,我可以使用更短的方法来解析:
doc = Nokogiri::XML(str)
现在找到并删除标签及其内容:
doc.at('EMAIL').remove
puts doc.to_xml
# >> Great, I will send you something at 888@gmail.com.
at
使用CSS选择器查找名为<EMAIL>
的第一个标记。还有其他相关方法可以找到所有匹配的标记或特定于CSS或XPath选择器。
XML / HTML解析器将文本分解为节点,便于查找和操作它们。文本可以更改,只要它是有效的HTML或XML,正确编写的代码将继续工作。
查看强制性的&#34; RegEx match open tags except XHTML self-contained tags&#34;。
如果存在嵌入的重复标记,则正则表达式会严重崩溃,例如:
<b>bold <i>italic <b>another bold</b></i></b>
尝试仅使用模式剥离<b>
标记会很痛苦。使用解析器更容易完成。
如果我在没有使用解析器的情况下完全坚持并且决定这样做,那么这将起作用:
foo = "Great, I will send you something at 888@gmail.com.\n <EMAIL><ADDRESS>asdf</ADDRESS><SUBJECT>sdfg</SUBJECT>\n <BODY>dfgh</BODY></EMAIL>"
foo.gsub(%r#<EMAIL>.*?</EMAIL>#im, '').strip
# => "Great, I will send you something at 888@gmail.com."
或者:
foo.gsub(%r#\s*<EMAIL>.*?</EMAIL>\s*#im, '')
# => "Great, I will send you something at 888@gmail.com."
我更喜欢这两个中的第一个,因为它在视觉上更清晰。
使用i
标志使模式不区分大小写:它会匹配<email>
和<EMAIL>
。使用m
标记允许.
将行尾视为普通字符。默认情况下将它们视为特殊情况,这使得带有嵌入式行尾的字符串被视为多行。
我不愿意,因为它会使格式化和输入更具限制性
有时在模式中删除类似尾随换行符的内容会更容易,然后再重新添加。如果选择在维护一些Ruby代码或复杂模式之间,我会选择Ruby代码。模式是强大的,我使用它们,但它们并不是一切的答案。