2014-12-29 3 views
6

У меня есть строка с большим количеством слов, и у меня есть текстовый файл, содержащий некоторые Stopwords, которые мне нужно удалить из моей строки. Скажем, у меня есть строкаУдаление стоп-слов из строки в Java

s="I love this phone, its super fast and there's so much new and cool things with jelly bean....but of recently I've seen some bugs." 

После удаления стоп-слов, строка должна быть как:

"love phone, super fast much cool jelly bean....but recently bugs." 

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

"love phone, super fast there's much and cool with jelly bean....but recently seen bugs" 

Вот мой файл stopwordslist.txt: Stopwords

Как решить эту проблему. Вот что я сделал до сих пор:

int k=0,i,j; 
ArrayList<String> wordsList = new ArrayList<String>(); 
String sCurrentLine; 
String[] stopwords = new String[2000]; 
try{ 
     FileReader fr=new FileReader("F:\\stopwordslist.txt"); 
     BufferedReader br= new BufferedReader(fr); 
     while ((sCurrentLine = br.readLine()) != null){ 
      stopwords[k]=sCurrentLine; 
      k++; 
     } 
     String s="I love this phone, its super fast and there's so much new and cool things with jelly bean....but of recently I've seen some bugs."; 
     StringBuilder builder = new StringBuilder(s); 
     String[] words = builder.toString().split("\\s"); 
     for (String word : words){ 
      wordsList.add(word); 
     } 
     for(int ii = 0; ii < wordsList.size(); ii++){ 
      for(int jj = 0; jj < k; jj++){ 
       if(stopwords[jj].contains(wordsList.get(ii).toLowerCase())){ 
        wordsList.remove(ii); 
        break; 
       } 
      } 
     } 
     for (String str : wordsList){ 
      System.out.print(str+" "); 
     } 
    }catch(Exception ex){ 
     System.out.println(ex); 
    } 
+0

бы разделив строку первой помощи? что-то вроде «phrase.split (delims)»; вы можете отфильтровать ненужные части перед их повторным сшиванием. это может решить вашу «эту» и «свою» проблему. –

+0

[Более конкретный вопрос здесь] (http://stackoverflow.com/questions/22257598/best-way-to-remove-stop-words-from-files) – jsroyal

ответ

2

Ошибка в том, что вы удаляете элемент из списка, в который вы переходите. Сообщите, что у вас есть wordsList, который содержит |word0|word1|word2| Если ii равно 1, и если проверка истинна, то вы вызываете wordsList.remove(1);. После этого ваш список |word0|word2|. ii затем увеличивается и равен 2, и теперь он превышает размер вашего списка, поэтому word2 никогда не будет проверен.

Оттуда есть несколько решений. Например, вместо удаления значений вы можете установить значение в значение "". Или создайте специальный список «результат».

1

Вот попробуйте следующий способ:

String s="I love this phone, its super fast and there's so much new and cool things with jelly bean....but of recently I've seen some bugs."; 
    String stopWords[]={"love","this","cool"}; 
    for(int i=0;i<stopWords.length;i++){ 
     if(s.contains(stopWords[i])){ 
      s=s.replaceAll(stopWords[i]+"\\s+", ""); //note this will remove spaces at the end 
     } 
    } 
    System.out.println(s); 

Таким образом, вы окончательный вывод будет без слов, которые вы не хотите в нем. Просто получите список стоп-слов в массиве и замените нужную строку.
Выход для моих игнорируемых слов:

I phone, its super fast and there's so much new and things with jelly bean....but of recently I've seen some bugs. 
+1

после цикла for, s = s.replaceAll (" "," <одно пространство> "); изменить два пространства на одно пространство? –

+0

Кроме того, как и в случае с Vimal's aswer, вы удаляете подстроки из середины других слов (попробуйте добавить «a» в качестве стоп-слова;) –

1

Вместо почему бы вам не использовать ниже подхода. Это будет легче читать и понимать:

for(String word : words){ 
    s = s.replace(word+"\\s*", ""); 
} 
System.out.println(s);//It will print removed word string. 
+0

обратите внимание, что эта реализация приведет к двум пробелам. –

+0

Проблема в том, что он также удалит временные слова между другими словами. Подобно этому, он также удаляет «свой» из «этого». – JavaLearner

+0

@AngelKoh Спасибо, что указали, что :) –

4

Это гораздо более элегантное решение (ИМХО), используя только регулярные выражения:

// instead of the ".....", add all your stopwords, separated by "|" 
    // "\\b" is to account for word boundaries, i.e. not replace "his" in "this" 
    // the "\\s?" is to suppress optional trailing white space 
    Pattern p = Pattern.compile("\\b(I|this|its.....)\\b\\s?"); 
    Matcher m = p.matcher("I love this phone, its super fast and there's so much new and cool things with jelly bean....but of recently I've seen some bugs."); 
    String s = m.replaceAll(""); 
    System.out.println(s); 
+0

Это не заявление о нарушении во всех проблемах. Он берет в первом цикле первое слово текста. Затем он смотрит в список стоп-слов, если он присутствует. Если он найдет слово в списке записями, он сломает цикл поиска. Затем он берет следующее слово и снова ищет в списке. –

+0

Да, удаление перерыва еще не решило проблему – JavaLearner

+0

, как и в случае с другими ответами, вы удалите временные слова, которые являются подстроками обычных слов. –

0

Попробуйте использовать replaceAll апи из строки, как:

String myString = "I love this phone, its super fast and there's so much new and cool things with jelly bean....but of recently I've seen some bugs."; 
String stopWords = "I|its|with|but"; 
String afterStopWords = myString.replaceAll("(" + stopWords + ")\\s*", ""); 
System.out.println(afterStopWords); 

OUTPUT: 
love this phone, super fast and there's so much new and cool things jelly bean....of recently 've seen some bugs. 
5

Попробуйте следующую программу.

String s="I love this phone, its super fast and there's so" + 
      " much new and cool things with jelly bean....but of recently I've seen some bugs."; 
    String[] words = s.split(" "); 
    ArrayList<String> wordsList = new ArrayList<String>(); 
    Set<String> stopWordsSet = new HashSet<String>(); 
    stopWordsSet.add("I"); 
    stopWordsSet.add("THIS"); 
    stopWordsSet.add("AND"); 
    stopWordsSet.add("THERE'S"); 

    for(String word : words) 
    { 
     String wordCompare = word.toUpperCase(); 
     if(!stopWordsSet.contains(wordCompare)) 
     { 
      wordsList.add(word); 
     } 
    } 

    for (String str : wordsList){ 
     System.out.print(str+" "); 
    } 

ВЫВОД: любовь телефона, его супер быстро так много новых интересных вещей с бобом желе .... но в последнее время я видел некоторые ошибки.

+0

Хороший улов, не удаляя ненужные, но добавляя нужные! +1 – Charlie

0

Попробуйте сохранить стоп-слова в наборе коллекций, а затем переименуйте строку в список. Чтобы получить результат, вы можете просто использовать 'removeAll'.

Set<String> stopwords = new Set<>() 
//fill in the set with your file 

String s="I love this phone, its super fast and there's so much new and cool things with jelly bean....but of recently I've seen some bugs."; 
List<String> listOfStrings = asList(s.split(" ")); 

listOfStrings.removeAll(stopwords); 
StringUtils.join(listOfStrings, " "); 

Нет необходимости в петлях - они обычно означают проблемы.

2

Вы можете использовать заменить все функции, как этот

String yourString ="I love this phone, its super fast and there's so much new and cool things with jelly bean....but of recently I've seen some bugs." 
yourString=yourString.replaceAll("stop" ,""); 
0

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

Вы должны попытаться изменить код:

От:

for(int ii = 0; ii < wordsList.size(); ii++){ 
    for(int jj = 0; jj < k; jj++){ 
     if(stopwords[jj].contains(wordsList.get(ii).toLowerCase())){ 
      wordsList.remove(ii); 
      break; 
     } 
    } 
} 

Чтобы что-то вроде:

for(int ii = 0; ii < wordsList.size(); ii++) 
{ 
    for(int jj = 0; jj < k; jj++) 
    { 
     if(wordsList.get(ii).toLowerCase().contains(stopwords[jj]) 
     { 
      wordsList.remove(ii); 
     } 
    } 
} 

Обратите внимание, что break удаляется и stopword.contains(word) изменяется на word.contains(stopword).

-1

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

https://github.com/uttesh/exude

 <dependency> 
     <groupId>com.uttesh</groupId> 
     <artifactId>exude</artifactId> 
     <version>0.0.2</version> 
    </dependency> 
+0

Это багги-библиотека – MFARID

+0

@MFARID не могли бы вы объяснить, на каком основании это багги-библиотека? –