Удаление строк из другой строки в Java
Допустим, у меня есть этот список слов:
String[] stopWords = new String[]{"i","a","and","about","an","are","as","at","be","by","com","for","from","how","in","is","it","not","of","on","or","that","the","this","to","was","what","when","where","who","will","with","the","www"};
Чем у меня текст
String text = "I would like to do a nice novel about nature AND people"
Есть ли метод, который соответствует stopWords и удаляет их, игнорируя регистр; как то где то там?
String noStopWordsText = remove(text, stopWords);
Результат:
" would like do nice novel nature people"
Если вы знаете о регулярных выражениях, это прекрасно работает, но я бы действительно предпочел что-то вроде общего решения, которое немного ориентировано на производительность.
Кстати, сейчас я использую этот метод, который не имеет надлежащей нечувствительной обработки регистра:
private static final String[] stopWords = new String[]{"i", "a", "and", "about", "an", "are", "as", "at", "be", "by", "com", "for", "from", "how", "in", "is", "it", "not", "of", "on", "or", "that", "the", "this", "to", "was", "what", "when", "where", "who", "will", "with", "the", "www", "I", "A", "AND", "ABOUT", "AN", "ARE", "AS", "AT", "BE", "BY", "COM", "FOR", "FROM", "HOW", "IN", "IS", "IT", "NOT", "OF", "ON", "OR", "THAT", "THE", "THIS", "TO", "WAS", "WHAT", "WHEN", "WHERE", "WHO", "WILL", "WITH", "THE", "WWW"};
private static final String[] blanksForStopWords = new String[]{"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""};
noStopWordsText = StringUtils.replaceEach(text, stopWords, blanksForStopWords);
4 ответа
Это решение, которое не использует регулярные выражения. Я думаю, что он уступает моему другому ответу, потому что он намного длиннее и менее понятен, но если производительность действительно, действительно важна, то это O(n), где n - длина текста.
Set<String> stopWords = new HashSet<String>();
stopWords.add("a");
stopWords.add("and");
// and so on ...
String sampleText = "I would like to do a nice novel about nature AND people";
StringBuffer clean = new StringBuffer();
int index = 0;
while (index < sampleText.length) {
// the only word delimiter supported is space, if you want other
// delimiters you have to do a series of indexOf calls and see which
// one gives the smallest index, or use regex
int nextIndex = sampleText.indexOf(" ", index);
if (nextIndex == -1) {
nextIndex = sampleText.length - 1;
}
String word = sampleText.substring(index, nextIndex);
if (!stopWords.contains(word.toLowerCase())) {
clean.append(word);
if (nextIndex < sampleText.length) {
// this adds the word delimiter, e.g. the following space
clean.append(sampleText.substring(nextIndex, nextIndex + 1));
}
}
index = nextIndex + 1;
}
System.out.println("Stop words removed: " + clean.toString());
Создайте регулярное выражение со своими стоп-словами, сделайте его нечувствительным к регистру, а затем используйте совпадение replaceAll
способ заменить все совпадения пустой строкой
import java.util.regex.*;
Pattern stopWords = Pattern.compile("\\b(?:i|a|and|about|an|are|...)\\b\\s*", Pattern.CASE_INSENSITIVE);
Matcher matcher = stopWords.matcher("I would like to do a nice novel about nature AND people");
String clean = matcher.replaceAll("");
...
в шаблоне только я ленив, продолжаю список стоп-слов.
Другой метод - перебрать все стоп-слова и использовать String
"s replaceAll
метод. Проблема с этим подходом заключается в том, что replaceAll
скомпилирует новое регулярное выражение для каждого вызова, поэтому его не очень эффективно использовать в циклах. Кроме того, вы не можете передать флаг, который делает регулярное выражение нечувствительным к регистру при использовании String
"s replaceAll
,
Изменить: я добавил \b
вокруг шаблона, чтобы он соответствовал только целым словам. Я также добавил \s*
чтобы после этого загромождать все пробелы, возможно, в этом нет необходимости.
Вы можете сделать выражение reg, чтобы соответствовать всем стоп- словам [например, a
, обратите внимание на пробел здесь] и в конечном итоге
str.replaceAll(regexpression,"");
ИЛИ ЖЕ
String[] stopWords = new String[]{" i ", " a ", " and ", " about ", " an ", " are ", " as ", " at ", " be ", " by ", " com ", " for ", " from ", " how ", " in ", " is ", " it ", " not ", " of ", " on ", " or ", " that ", " the ", " this ", " to ", " was ", " what ", " when ", " where ", " who ", " will ", " with ", " the ", " www "};
String text = " I would like to do a nice novel about nature AND people ";
for (String stopword : stopWords) {
text = text.replaceAll("(?i)"+stopword, " ");
}
System.out.println(text);
выход:
would like do nice novel nature people
Там может быть лучший способ.
Трещина text
в то время как пространство. Затем переберите массив и продолжайте добавлять к StringBuilder
только если это не одно из стоп-слов.