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