Как найти целое слово в строке в java

У меня есть строка, которую я должен разобрать для разных ключевых слов. Например, у меня есть строка:

и мои слова

'123woods' "Вудс"!--1-->

Я должен сообщить, когда у меня есть матч и где. Следует также учитывать несколько случаев. Однако для этого я должен получить матч только на 123woods, а не на woods. Это исключает использование строки.contains() метод. Кроме того, я должен иметь возможность иметь список / набор ключевых слов и одновременно проверять их появление. В этом примере, если у меня есть "123woods" и "come", я должен получить два случая. Выполнение метода должно быть несколько быстрым для больших текстов.

моя идея-использовать StringTokenizer, но я не уверен, что он будет хорошо работать. Есть предложения?

13 ответов


приведенный ниже пример основан на ваших комментариях. Он использует список ключевых слов, которые будут искать в данной строке, используя границы слов. Он использует StringUtils из Apache Commons Lang для создания регулярного выражения и печати сопоставленных групп.

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: высокопроизводительные алгоритмы сопоставления шаблонов в Java.


используйте regex + границы слов, как ответили другие.

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

будет правда.

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

будет false.


Как насчет чего-то вроде Arrays.asList(String.split(" ")).contains("xx")?

посмотреть строку.split () и как я могу проверить, содержит ли массив определенное значение.


надеюсь, это сработает для вас:

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/


попробуйте сопоставить с помощью регулярных выражений. Матч для "\b123wood\b", \B является разрывом слов.


есть способ матч слово С строка в Android:

String full = "Hello World. How are you ?";

String one = "Hell";
String two = "Hello";
String three = "are";
String four = "ar";


boolean is1 = isContainExactWord(full, one);
boolean is2 = isContainExactWord(full, two);
boolean is3 = isContainExactWord(full, three);
boolean is4 = isContainExactWord(full, four);

Log.i("Contains Result", is1+"-"+is2+"-"+is3+"-"+is4);

Result: false-true-true-false

гораздо более простой способ сделать это-использовать сплит():

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;

это более простой, менее элегантный способ сделать то же самое без использования токенов и т. д.


решение вроде бы давно принято, но решение может быть улучшено, поэтому если у кого-то есть похожие проблемы:

Это классическое приложение для алгоритмов с несколькими шаблонами поиска.

Поиск шаблонов Java (с помощью Matcher.find) не подходит для этого. Поиск ровно одного ключевого слова оптимизирован в java, поиск выражения or использует regex недетерминированный автомат, который возвращается на несоответствия. В худшем случае каждый символ текст будет обрабатываться l раз (где l-сумма длин шаблонов).

поиск по одному шаблону лучше,но тоже не квалифицирован. Нужно будет начать весь поиск по каждому шаблону ключевых слов. В худшем случае каждый символ текста будет обработан p раз, где p-количество шаблонов.

Multi pattern search будет обрабатывать каждый символ текста ровно один раз. Алгоритмы, подходящие для такого поиска, будут Aho-Corasick, Wu-Manber или Set Обратное Соответствие Oracle. Их можно найти в библиотеках, таких как Stringsearchalgorithms или byteseek.

// 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();

можно использовать регулярные выражения. Используйте методы Matcher и Pattern, чтобы получить желаемый результат


вы также можете использовать регулярное выражение, соответствующее флагу \b (вся граница слова).


чтобы соответствовать "123woods" вместо "woods", используйте атомную группировку в регулярном выражении. Следует отметить, что в строке , соответствующей только "123woods", она будет соответствовать первой "123woods" и выходит вместо поиска той же строки дальше.

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

он ищет 123woods в качестве основного поиска, как только он получил соответствие, он выходит из поиска.


оглядываясь на исходный вопрос, мы должны найти некоторые ключевые слова в заданном предложении подсчитать количество вхождений и знать что-то о том, где. Я не совсем понимаю, что означает" где " (это индекс в предложении?), так что я пас... Я все еще изучаю java, шаг за шагом, поэтому я позабочусь об этом в свое время: -)

следует отметить, что общие предложения (как и в исходном вопросе) могут иметь повторяющиеся ключевые слова, поэтому поиск не может просто спросить, существует ли данное ключевое слово "существует или нет" и считать его 1, если оно существует. Может быть больше одного и того же. Например:

// Base sentence (added punctuation, to make it more interesting):
String sentence = "Say that 123 of us will come by and meet you, "
                + "say, at the woods of 123woods.";

// Split it (punctuation taken in consideration, as well):
java.util.List<String> strings = 
                       java.util.Arrays.asList(sentence.split(" |,|\."));

// My keywords:
java.util.ArrayList<String> keywords = new java.util.ArrayList<>();
keywords.add("123woods");
keywords.add("come");
keywords.add("you");
keywords.add("say");

посмотрев на него, ожидаемый результат будет 5 для "Say" + "come" + " you " + " say " + "123woods", считая" say " дважды, если мы перейдем в нижний регистр. Если мы этого не делаем, то количество должно быть 4, "сказать" исключено и "сказать" включено. Штраф. Мое предложение:

// Set... ready...?
int counter = 0;

// Go!
for(String s : strings)
{
    // Asking if the sentence exists in the keywords, not the other
    // around, to find repeated keywords in the sentence.
    Boolean found = keywords.contains(s.toLowerCase());
    if(found)
    {
        counter ++;
        System.out.println("Found: " + s);
    }
}

// Statistics:
if (counter > 0)
{
    System.out.println("In sentence: " + sentence + "\n"
                     + "Count: " + counter);
}

и результаты являются:

Найдено: Сказать
Найдено: пришел
Найдено: вы
Найдено: сказать
Найдено: 123woods
В предложении: скажите, что 123 из нас придут и встретят вас, скажем, в лесу 123woods.
Граф: 5


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" );
        }
    }
}