匹配可能包含保留字符的子字符串

时间:2016-11-21 20:19:21

标签: ruby regex

如果我正在测试的字符串包含正则表达式字符,我遇到了将一个字符串与另一个字符串匹配的问题。

背景:我正在开发一个脚本,将新闻文章从2个遗留系统迁移到一个。在某些情况下,这些故事在系统中是重复的,所以我正在运行一个脚本来检查存储数据的存档文件(以html格式),以查看当前故事的标题是否与存档中的任何内容匹配。

#...(for each line) 
line.match(title) then
    return true
end

这通常有效,除非我在标题中有正则表达式字符,例如:

<span class="title">$8.9 Million Grant for UC Center Focused on Occupational Safety and Health</span>

不符合

$8.9 Million Grant for UC Center Focused on Occupational Safety and Health

以下是来自irb的示例输出以演示

2.3.0 :012 > str = '<span class="title">$8.9 Million Grant for UC Center Focused on Occupational Safety and Health</span>'
2.3.0 :020 > str.match("$8.9 Million Grant for UC Center Focused on Occupational Safety and Health")
 => nil 
2.3.0 :021 > str.match("\\$8.9 Million Grant for UC Center Focused on Occupational Safety and Health")
 => #<MatchData "$8.9 Million Grant for UC Center Focused on Occupational Safety and Health"> 
2.3.0 :022 > str.match("8.9 Million Grant for UC Center Focused on Occupational Safety and Health")
 => #<MatchData "8.9 Million Grant for UC Center Focused on Occupational Safety and Health"> 
2.3.0 :023 > 

所以我很确定$是问题所在,问题源于它是一个递归的正则表达式字符。

Ruby不是我的日常用语,而且我在查找在哪里查看是否有红宝石方法来执行匹配而不依赖于正则表达式,或者按字面意思处理模式或自动逃避潜在的正则表达式特殊字符。感谢帮助。

2 个答案:

答案 0 :(得分:2)

如果您不需要MatchData(例如字符串中出现目标文本的位置),那么使用String#include?的更简单的解决方案是:

str.include?("$8.9 Million")
# => true

如果你需要匹配发生的位置,使用String#index仍然更简单:

str.index("$8.9 Million")
# => 20

答案 1 :(得分:1)

str.match(Regexp.new(Regexp.escape("$8.9 Million ...")))
=> #<MatchData "$8.9 Million Grant for UC Center Focused...