TL; DRを簡単なストリングについては、最善のが、ためです一致する全単語だけ正規表現がおそらく良いです。
どの方法が効率的かを確認する最も良い方法は、テストすることです。
String.indexOf()
の代わりにString.contains()
を使用すると、正規表現以外のコードを簡略化できます。
は、正規表現は、このようになります別の単語を検索するには、次の正規表現で
OR
として
apple|orange|pear|banana|kiwi
|
作品。
私の非常に簡単なテストコードは次のようになります。
public class TestContains {
private static String containsWord(Set<String> words,String sentence) {
for (String word : words) {
if (sentence.contains(word)) {
return word;
}
}
return null;
}
private static String matchesPattern(Pattern p,String sentence) {
Matcher m = p.matcher(sentence);
if (m.find()) {
return m.group();
}
return null;
}
public static void main(String[] args) {
Set<String> words = new HashSet<String>();
words.add("apple");
words.add("orange");
words.add("pear");
words.add("banana");
words.add("kiwi");
Pattern p = Pattern.compile("apple|orange|pear|banana|kiwi");
String noMatch = "The quick brown fox jumps over the lazy dog.";
String startMatch = "An apple is nice";
String endMatch = "This is a longer sentence with the match for our fruit at the end: kiwi";
long start = System.currentTimeMillis();
int iterations = 10000000;
for (int i = 0; i < iterations; i++) {
containsWord(words, noMatch);
containsWord(words, startMatch);
containsWord(words, endMatch);
}
System.out.println("Contains took " + (System.currentTimeMillis() - start) + "ms");
start = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
matchesPattern(p,noMatch);
matchesPattern(p,startMatch);
matchesPattern(p,endMatch);
}
System.out.println("Regular Expression took " + (System.currentTimeMillis() - start) + "ms");
}
}
次のように私が得た結果は以下のとおりであった:
Contains took 5962ms
Regular Expression took 63475ms
明らかにタイミングが検索された単語の数に応じて変動します文字列が検索されていますが、はこのような簡単な検索のために正規表現より10倍高速です。
正規表現を使用して別のString内の文字列を検索すると、あなたはナットを壊すためにスレッジハンマーを使用しているので、私はそれがより遅いことに驚かされるべきではないと思います。検索するパターンがより複雑な場合の正規表現を保存します。あなただけの、例えば単語全体だけでなく、サブストリングを、一致させたいのでindexOf()
とが仕事をしない場合は、正規表現を使用したい場合があり
一つのケースがありますpear
に一致しますが、spears
に一致しません。正規表現はword boundariesという概念を持っているので、このケースをうまく処理します。
\b(apple|orange|pear|banana|kiwi)\b
\b
のみOR式一緒に先頭または単語の終わりとブラケットグループに一致するように言う:
は、このケースでは、私たちにパターンを変更すると思います。あなたのコード内でこのパターンを定義するとき 注意、あなたは別のバックスラッシュでバックスラッシュをエスケープする必要があります。ここでは
Pattern p = Pattern.compile("\\b(apple|orange|pear|banana|kiwi)\\b");
あなたはちょうど読むことができませんか?効率的だとは決して言いませんでした。 –
パフォーマンスは正規表現の長さによって異なります。 1000文字未満の場合は、それに進みます。それ以上の場合は、他の解決策が必要です。たとえば、テキストを分割して単語を分離し、あらかじめ定義された「既知の」単語のハッシュテーブル/セットと照合します。 – AlexR
@deporter答えの目的は、完璧で、光沢のある、世界クラスのソリューションを提供しないように質問を解決する方法のヒントを与えることです。これは簡単に改善することができ、読みやすくするために、200文字列(regexpを使用しないもう1つの理由)があれば、forループを使用して 'StringBuilder'で連結することができます。私の答えは十分な味を提供すると思います。 –