Допустим, у вас есть такой текстовый файл: http://www.gutenberg.org/files/17921/17921-8.txt
Есть ли у кого-нибудь хороший алгоритм или открытый код для извлечения слов из текстового файла? Как получить все слова, избегая при этом специальных символов и сохраняя такие вещи, как «это» и т. д.
Я работаю на Яве. Спасибо




Вы можете попробовать регулярное выражение, используя созданный вами шаблон, и подсчитать, сколько раз этот шаблон был найден.
Псевдокод будет выглядеть так:
create words, a list of words, by splitting the input by whitespace
for every word, strip out whitespace and punctuation on the left and the right
Код на Python будет примерно таким:
words = input.split()
words = [word.strip(PUNCTUATION) for word in words]
где
PUNCTUATION = ",. \n\t\\\"'][#*:"
или любые другие символы, которые вы хотите удалить.
Я считаю, что у Java есть эквивалентные функции в классе String: Нить.split ().
Результат выполнения этого кода в тексте, который вы указали в своей ссылке:
>>> print words[:100]
['Project', "Gutenberg's", 'Manual', 'of', 'Surgery', 'by', 'Alexis',
'Thomson', 'and', 'Alexander', 'Miles', 'This', 'eBook', 'is', 'for',
'the', 'use', 'of', 'anyone', 'anywhere', 'at', 'no', 'cost', 'and',
'with', 'almost', 'no', 'restrictions', 'whatsoever', 'You', 'may',
'copy', 'it', 'give', 'it', 'away', 'or', 're-use', 'it', 'under',
... etc etc.
Да, в Java есть метод «разделения», но он не имеет эквивалента методу «полосы».
В принципе, вы хотите сопоставить
([A-Za-z]) + ('([A-Za-z]) *)?
Правильно?
Похоже, это правильная работа для регулярных выражений. Вот некоторый код Java, чтобы дать вам представление, если вы не знаете, с чего начать:
String input = "Input text, with words, punctuation, etc. Well, it's rather short.";
Pattern p = Pattern.compile("[\\w']+");
Matcher m = p.matcher(input);
while ( m.find() ) {
System.out.println(input.substring(m.start(), m.end()));
}
Шаблон [\w']+ соответствует всем символам слова и апострофу несколько раз. Строка примера будет напечатана пословно. Взгляните на Документация по классу Java Pattern, чтобы узнать больше.
Мне пришлось немного изменить регулярное выражение, чтобы не включать числа, подчеркивание и слова, начинающиеся с цитаты, но в остальном - хорошо!
Мне пришлось убежать от \ w вот так: Pattern.compile("[\\w']+");
Это немного не по теме, но как исключить одинарные кавычки в начале или в конце слова?
@ScrollerBlaster Для этого вы можете использовать границы слов. Pattern.compile("\\b[\\w']+\\b");
Pattern.compile("\\w[\\w-]+('\\w+)?") поддерживает слова с дефисом и даже слова с несколькими дефисами (sous-vide, mise-en-scène), а также поддерживает апостроф, но не в начале слова, и за ним должно следовать больше букв слова (I've, sous-vide'n). Возможно, вы захотите разрешить больше букв после апострофа (т.е. включить притяжательные формы множественного числа), и в этом случае используйте Pattern.compile("\\w[\\w-]+('\\w*)?").
он распознает числа как слова, как их удалить? Не узнавая «я».
Вот хороший подход к вашей проблеме: Эта функция получает ваш текст в качестве входных данных и возвращает массив всех слов внутри данного текста.
private ArrayList<String> get_Words(String SInput){
StringBuilder stringBuffer = new StringBuilder(SInput);
ArrayList<String> all_Words_List = new ArrayList<String>();
String SWord = "";
for(int i=0; i<stringBuffer.length(); i++){
Character charAt = stringBuffer.charAt(i);
if (Character.isAlphabetic(charAt) || Character.isDigit(charAt)){
SWord = SWord + charAt;
}
else{
if (!SWord.isEmpty()) all_Words_List.add(new String(SWord));
SWord = "";
}
}
return all_Words_List;
}
Преимущество этого кода перед регулярными выражениями состоит в том, что это можно сделать просто за один проход.