0

我需要一个匹配此文本的正则表达式:

894975||0||Lever 2000 Anti-Bacterial Bar Soap ||Health & Spa/Personal Care/Body Care/Soap

我想搜索文本,并在两组管道后匹配“Bar Soap”。

如果单词不按顺序排列,则不匹配。我的正则表达式是:

/^(?:\d+\|\|).?\|\|[^|]*?(Bar[^|]*? Soap)/i 

当“soap”排在第一位,“bar”排在第二位时,这不匹配。

4

2 回答 2

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

[添加]

如果你想使用变量 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
于 2012-12-08T07:14:35.957 回答
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 将正确处理解码嵌入式管道。

因为只有一个样本输入行,所以这个解决方案再彻底不过了。

于 2012-12-08T22:14:00.277 回答