Java регулярное выражение для поиска двух слов, которые встречаются близко друг к другу - PullRequest
1 голос
/ 04 ноября 2011

Я пытаюсь написать регулярное выражение, которое будет подсчитывать количество раз, когда два слова встречаются в определенной близости (в пределах 5 слов друг от друга) в строке, без двойного счета слов.

Например, если бы у меня была строка:

"Человеку понравилась его большая шляпа. Шляпа была очень большой."

В этом случае регулярное выражение должно видеть«большая шляпа» в первом предложении и «большие шляпы» во втором предложении, возвращая в общей сложности 2. Обратите внимание, что во втором предложении есть несколько слов между «шляпой» и «большой», они также появляютсяв порядке, отличном от первого предложения, но они все еще встречаются в окне из 5 слов.

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

Ответы [ 4 ]

1 голос
/ 04 ноября 2011

Ну и дела ... весь этот код в других ответах ... как насчет этого однострочного решения:

int count = input.split("big( \\b.*?){1,5}hat").length + input.split("hat( \\b.*?){1,5}big").length - 2;
1 голос
/ 04 ноября 2011

Немного похоже на Стивена С. Но использование библиотечных классов для помощи в механике.

    String input = "The man liked his big hat. The hat was very big";
    int proximity = 5;

    // split input into words
    String[] words = input.split("[\\W]+");

    // create a Deque of the first <proximity> words
    Deque<String> haystack = new LinkedList<String>(Arrays.asList(Arrays.copyOfRange(words, 0, proximity)));

    // count duplicates in the first <proximity> words
    int count = haystack.size() - new HashSet<String>(haystack).size();
    System.out.println("initial matches: " + count);

    // process the rest of the words
    for (int i = proximity; i < words.length; i++) {
        String word = words[i];
        System.out.println("matching '" + word + "' in [" + haystack + "]");

        if (haystack.contains(word)) {
            System.out.println("matched word " + word + " at index " + i);
            count++;
        }

        // remove the first word
        haystack.removeFirst();
        // add the current word
        haystack.addLast(word);
    }

    System.out.println("total matches:" + count);
1 голос
/ 04 ноября 2011

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

Регулярные выражения могут работать, но они не лучший способ сделать это.

Лучший способ сделать это - разбить входную строку на последовательность слов (например, используя String.split(...)), а затем перебрать последовательность примерно так:

String[] words = input.split("\\s");
int count = 0;
for (int i = 0; i < words.length; i++) {
    if (words[i].equals("big")) {
        for (int j = i + 1; j < words.length && j - i < 5; j++) {
            if (words[j].equals("hat")) {
                count++;
            }
        }
    }
}
// And repeat for "hat" followed by "big".

Возможно, вам придется изменить это в зависимости от того, что именно вы пытаетесь считать, но это общая идея.


Если вам нужно сделать это для многих, многих комбинаций слов, то стоило бы искать более эффективное решение. Но в качестве варианта использования с однократным или малым объемом лучше всего использовать самый простой.

0 голосов
/ 04 ноября 2011

Это регулярное выражение будет соответствовать каждому вхождению двух слов, которые встречаются в 5 словах друг от друга

([a-zA-Z]+)(?:[^ ]* ){0,5}\1[^a-zA-Z]
  • ([a-zA-Z]+) будет соответствовать слову, если вы можете найти совпадение [0-9] в ваших словах, которые вы можете заменить ([a-zA-Z0-9] +).

  • (?:[^ ]* ){0,5} для соответствия от 0 до 5 слов

  • \1[^a-zA-Z] в соответствии с повторением вашего слова

Затем вы можете использовать это с шаблоном и находить каждый случай повторения слова

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...