31

さまざまなキーワードを解析する必要がある文字列があります。たとえば、私は文字列を持っています:

「123の森で会いに行きます」

そして私のキーワードは

「123ウッズ」
「ウッズ」

試合があるときはいつでもどこで報告する必要があります。複数回の発生も考慮する必要があります。

ただし、これについては、 'woods' ではなく '123woods' でのみ一致するはずです。これにより、メソッドを使用する必要がなくなります。また、キーワードのリスト/セットを取得し、同時にそれらの発生を確認できる必要があります。この例では、'123woods''come'がある場合、2 つのオカレンスを取得する必要があります。メソッドの実行は、大きなテキストでは多少速くなるはずです。String.contains()

私の考えは使用するStringTokenizerことですが、うまく機能するかどうかはわかりません。助言がありますか?

4

13 に答える 13

49

以下の例は、コメントに基づいています。これは、単語境界を使用して特定の文字列で検索されるキーワードのリストを使用します。Apache Commons Lang の StringUtils を使用して正規表現を作成し、一致したグループを出力します。

String text = "I will come and meet you at the woods 123woods and all the woods";

List<String> tokens = new ArrayList<String>();
tokens.add("123woods");
tokens.add("woods");

String patternString = "\\b(" + StringUtils.join(tokens, "|") + ")\\b";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(text);

while (matcher.find()) {
    System.out.println(matcher.group(1));
}

より高いパフォーマンスを求めている場合は、StringSearch : high-performance pattern matching algorithm in Java を参照してください。

于 2011-02-23T12:50:43.267 に答える
19

他の人が答えたように、正規表現と単語の境界を使用してください。

"I will come and meet you at the 123woods".matches(".*\\b123woods\\b.*");

真になります。

"I will come and meet you at the 123woods".matches(".*\\bwoods\\b.*");

偽になります。

于 2011-02-23T12:56:34.010 に答える
12

これがうまくいくことを願っています:

String string = "I will come and meet you at the 123woods";
String keyword = "123woods";

Boolean found = Arrays.asList(string.split(" ")).contains(keyword);
if(found){
      System.out.println("Keyword matched the string");
}

http://codigounico.blogspot.com/

于 2011-02-23T14:02:15.047 に答える
9

のようなものはどうArrays.asList(String.split(" ")).contains("xx")ですか?

String.split()および配列に特定の値が含まれているかどうかをテストする方法を参照してください。

于 2011-02-23T12:50:35.667 に答える
4
public class FindTextInLine {
    String match = "123woods";
    String text = "I will come and meet you at the 123woods";

    public void findText () {
        if (text.contains(match)) {
            System.out.println("Keyword matched the string" );
        }
    }
}
于 2018-06-21T13:38:36.507 に答える
2

正規表現を使用して一致を試みます。「\b123wood\b」に一致、\b は単語の区切りです。

于 2011-02-23T12:51:38.630 に答える
2

解決策は長い間受け入れられているようですが、解決策は改善される可能性があるため、誰かが同様の問題を抱えている場合:

これは、マルチパターン検索アルゴリズムの古典的なアプリケーションです。

Java パターン検索 (with Matcher.find) は、それを行う資格がありません。正確に 1 つのキーワードの検索は Java で最適化されています。or 式の検索は、不一致でバックトラックする正規表現の非決定論的オートマトンを使用します。最悪の場合、テキストの各文字が l 回処理されます (l はパターンの長さの合計です)。

単一パターン検索の方が優れていますが、修飾もされていません。すべてのキーワード パターンの検索全体を開始する必要があります。最悪の場合、テキストの各文字が p 回処理されます。ここで、p はパターンの数です。

マルチパターン検索は、テキストの各文字を 1 回だけ処理します。このような検索に適したアルゴリズムは、Aho-Corasick、Wu-Manber、または Set Backwards Oracle Matching です。これらは、 Stringsearchalgorithmsbyteseekなどのライブラリで見つけることができます。

// example with StringSearchAlgorithms

AhoCorasick stringSearch = new AhoCorasick(asList("123woods", "woods"));

CharProvider text = new StringCharProvider("I will come and meet you at the woods 123woods and all the woods", 0);

StringFinder finder = stringSearch.createFinder(text);

List<StringMatch> all = finder.findAll();
于 2016-08-13T10:22:39.637 に答える
1

これを行うためのはるかに簡単な方法は、split()を使用することです。

String match = "123woods";
String text = "I will come and meet you at the 123woods";

String[] sentence = text.split();
for(String word: sentence)
{
    if(word.equals(match))
        return true;
}
return false;

これは、トークンなどを使用せずに同じことを行うための、より単純でエレガントではない方法です。

于 2012-10-11T00:12:48.697 に答える
0

正規表現を使用できます。Matcher メソッドと Pattern メソッドを使用して、目的の出力を取得します。

于 2011-02-23T12:49:09.680 に答える
0

\b フラグ (単語境界全体) で正規表現一致を使用することもできます。

于 2011-02-23T12:51:21.517 に答える
0

"woods" の代わりに "123woods" に一致させるには、正規表現でアトミック グループ化を使用します。注意すべきことの 1 つは、"123woods" のみに一致する文字列では、最初の "123woods" に一致し、同じ文字列をさらに検索する代わりに終了することです。

\b(?>123woods|woods)\b

一次検索として 123woods を検索し、一致すると検索を終了します。

于 2013-08-31T13:00:55.347 に答える