一致するキーワードがあるかどうかを確認するために、さまざまなアイテムの名前と説明をスキャンしています。
以下のコードでは、「googler」や「applecobbler」などを返します。これは、私がやろうとしていることが完全一致のみを取得する場合です。
[name, description].join(" ").downcase.scan(/apple|microsoft|google/)
どうすればいいですか?
一致するキーワードがあるかどうかを確認するために、さまざまなアイテムの名前と説明をスキャンしています。
以下のコードでは、「googler」や「applecobbler」などを返します。これは、私がやろうとしていることが完全一致のみを取得する場合です。
[name, description].join(" ").downcase.scan(/apple|microsoft|google/)
どうすればいいですか?
私の正規表現スキルはかなり弱いですが、単語境界を使用する必要があると思います:
[name, description].join(" ").downcase.scan(/\b(apple|microsoft|google)\b/)
欲しい情報にもよりますが、完全一致だけが欲しい場合は、比較部分に正規表現は必要ありません。関連する文字列を比較するだけです。
splitted_strings = [name, description].join(" ").downcase.split(/\b/)
splitted_strings & %w[apple microsoft google]
# => the words that match given in the order of appearance
質問と、私がそれらのことをしたい状況を見て、ソースのリストとそれに関連するテキストがあり、ヒットを知りたいと思った実際のプログラムに対して私がすることは次のとおりです。おそらく次のように書きます。
require 'pp'
names = ['From: Apple', 'From: Microsoft', 'From: Google.com']
descriptions = [
'"an apple a day..."',
'Microsoft Excel flight simulator... according to Microsoft',
'Searches of Google revealed multiple hits for "google"'
]
targets = %w[apple microsoft google]
regex = /\b(?:#{ Regexp.union(targets).source })\b/i
names.zip(descriptions) do |n,d|
name_hits, description_hits = [n, d].map{ |s| s.scan(regex) }
pp [name_hits, description_hits]
end
どの出力:
[["Apple"], ["apple"]]
[["Microsoft"], ["Microsoft", "Microsoft"]]
[["Google"], ["Google", "google"]]
これにより、単語の大文字と小文字が区別されるため、リンゴと会社を区別し、単語数を取得して、テキストの関連性を示すことができます。
次のregex
ようになります。
/\b(?:apple|microsoft|google)\b/i
大文字と小文字は区別されませんが、scan
単語は元の大文字と小文字で返されます。
names
、descriptions
およびtargets
すべてがデータベースまたは個別のファイルから取得される可能性があり、データをコードから分離するのに役立ち、ターゲットが変更されたときにコードを変更する必要がなくなります。ターゲット ワードのリストを使用し、Regexp.union を使用してパターンをすばやく構築します。
正規表現に適切な境界エンティティを追加します ( \b
)。メソッドを使用することもできます#grep
。参加する代わりに:
array.grep(your_regexp)