我需要一个与此文本匹配的正则表达式:
894975||0||Lever 2000 Anti-Bacterial Bar Soap ||Health & Spa/Personal Care/Body Care/Soap
我想搜索文本,并且在两组管道之后匹配“Bar Soap”。
如果单词不符合顺序则不匹配。 我的正则表达是:
/^(?:\d+\|\|).?\|\|[^|]*?(Bar[^|]*? Soap)/i
当“soap”首先出现并且“bar”为秒时,这不匹配。
答案 0 :(得分:2)
首先,将该行拆分为元素:
product = str.split(/\|\|/)[2]
然后,尝试检查它是否包含“bar”和“soap”:
puts "match" if product =~ /bar/i and product =~ /soap/i
puts "match" if product =~ /bar.*soap|soap.*bar/i
puts "match" if product =~ /(?=.*bar)(?=.*soap)/i
[ADDED]
如果你想使用变量match_terms,试试这个:
re = match_terms.split(/,/).map { |t| "(?=.*#{Regexp::quote t})" }.join ""
puts "match" if product =~ /#{re}/i
或
terms = match_terms.upcase.split(/,/)
puts "match" if terms.select { |t| product.upcase.include? t }.size == terms.size
答案 1 :(得分:0)
示例数据看起来像您从数据库提取中看到的标准管道分隔('|'
)文件。通常会在输出中看到具有空值的字段显示为||
。
不是尝试使用正则表达式来解析它,而是通常通过拆分管道来处理,或者通过管道而不是逗号作为列分隔符将其视为CSV记录。如果您获得该字段实际上具有内容的记录,则拆分双管道(||
)将失败。
这是两个不同的样本,显示我是如何做到的。第一个是将|
拆分为字段。
text = '894975||0||Lever 2000 Anti-Bacterial Bar Soap ||Health & Spa/Personal Care/Body Care/Soap'
fields = text.split('|')
此时 fields
看起来像:
[
[0] "894975",
[1] "",
[2] "0",
[3] "",
[4] "Lever 2000 Anti-Bacterial Bar Soap ",
[5] "",
[6] "Health & Spa/Personal Care/Body Care/Soap"
]
抓住第五个字段检索产品:
product = fields[4]
=> "Lever 2000 Anti-Bacterial Bar Soap"
第二种方法是将内容视为包含|
分隔符的CSV文件:
require 'csv'
text = <<EOT
894975||0||Lever 2000 Anti-Bacterial Bar Soap ||Health & Spa/Personal Care/Body Care/Soap
EOT
CSV.parse(text, :col_sep => '|') do |row|
puts row[4]
end
=> "Lever 2000 Anti-Bacterial Bar Soap"
使用CSV执行此操作的优点是可以在文本中找到|
字符,CSV将正确处理嵌入式管道的解码。
因为只有一个样本输入行,所以这个解决方案不能更彻底。