2014-12-29 15 views
6

Mam ciąg znaków z dużą ilością słów i mam plik tekstowy zawierający kilka słów kluczowych, które muszę usunąć z mojego ciągu. Powiedzmy mam StringUsuwanie stoperw z ciągu znaków w Javie

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." 

po usunięciu stopwords, łańcuch powinien być jak:

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

udało mi się to osiągnąć, ale problem jestem stoi to, że whenver istnieją sąsiadujące stopwords w ciągu jego usunięcie tylko pierwszy i jestem coraz wynik:

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

Oto mój plik stopwordslist.txt: Stopwords

Jak mogę rozwiązać ten problem. Oto co zrobiłem do tej pory:

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

byłoby dzielenie ciąg pierwszej pomocy? coś takiego jak "phrase.split (delims);" możesz odfiltrować niepożądane części przed ponownym łączeniem ich z powrotem. może to rozwiązać problem "ten" i "jego". –

+0

[Więcej szczegółowych pytań tutaj] (http://stackoverflow.com/questions/22257598/best-way-to-remove-stop-words-from-files) – jsroyal

Odpowiedz

2

Błąd polega na tym, że usuwasz element z listy, którą wykonujesz iteracyjnie. Powiedzmy, że masz wordsList, który zawiera |word0|word1|word2| Jeśli ii jest równy 1, a jeśli test jest prawdziwy, to wywołujemy wordsList.remove(1);. Następnie twoja lista to |word0|word2|. ii jest następnie zwiększany i jest równy 2, a teraz jest większy od rozmiaru listy, dlatego word2 nigdy nie będzie testowany.

Stamtąd istnieje kilka rozwiązań. Na przykład zamiast usuwania wartości możesz ustawić wartość na "". Lub utwórz specjalną listę "wyników".

1

oto spróbować następujący sposób:

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

ten sposób końcowy wynik będzie bez słów, które nie chcą w nim. Po prostu uzyskaj listę słów kończących w tablicy i zamień ją na wymagany ciąg.
wyjścia dla moich stopwords:

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

po pętli for, s = s.replaceAll (" "," "); zmienić dwie spacje na jedną przestrzeń? –

+0

Podobnie jak w przypadku Asfalmu Vimal, usuwałbyś łańcuchy z innych słów (spróbuj dodać "a" jako stopword;)) –

1

Zamiast dlaczego nie można skorzystać z poniższego podejścia. Będzie to łatwiejsze do odczytania i zrozumienia:

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

zwróć uwagę, że ta implementacja spowoduje dwie spacje. –

+0

Problem polega na tym, że usunie również stopw pomiędzy innymi słowami. Podobnie jak usuwa "jego" z "tego" również. – JavaLearner

+0

@AngelKoh Dzięki za zwrócenie uwagi, że :) –

4

Jest to znacznie bardziej eleganckie rozwiązanie (IMHO), przy użyciu wyrażeń tylko regularnych:

// 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

To nie jest oświadczenie o rozbiciu na cały problem. W pierwszej pętli bierze pierwsze słowo w tekście. Następnie przegląda listę stopwords, jeśli jest obecna. Jeśli znajdzie to słowo na liście stopów, przerwie pętlę wyszukiwania. Następnie bierze następne słowo i ponownie szuka na liście stopów. –

+0

Tak, usunięcie przerwy nie rozwiązało problemu – JavaLearner

+0

ponownie, tak jak w przypadku innych odpowiedzi, usuniesz stopery będące podciągami zwykłych słów. –

0

Spróbuj użyć replaceAll api String jak:

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

Wypróbuj poniższy program.

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

WYJŚCIE: miłość telefon, jego bardzo szybko, więc wiele nowych fajnych rzeczy z galaretką fasoli .... ale ostatnio widziałem kilka błędów.

+0

Przyjemny połów, nie usuwanie niechcianych, ale dodanie pożądanych! +1 – Charlie

0

Spróbuj zapisać zatrzymania w zestawie kolekcji, a następnie zrób token na liście. Możesz potem po prostu użyć "removeAll", aby uzyskać wynik.

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

Nie dla potrzebnych pętli - zwykle oznaczają problemy.

2

Można użyć wymienić wszystkie funkcje jak ten

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

Wydaje się, że zrobić przystanek jedno słowo przystanek jest usuwany w zdaniu przenieść do innego słowa STOP: trzeba usunąć wszystko zatrzymać słowa w każdym zdaniu .

Należy spróbować zmienić swój kod:

Od:

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

Aby coś takiego:

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

Zauważ, że break jest usuwany i stopword.contains(word) zmienia się na word.contains(stopword).

-1

Niedawno jeden z projektów wymagał funkcji filtrowania zatrzymania/stemma i przeklinania słów z podanego tekstu lub pliku, po przejrzeniu kilku blogów i napisów. utworzył prostą bibliotekę do filtrowania danych/pliku i udostępnioną w maven. mam nadzieję, że to może pomóc niektórym.

https://github.com/uttesh/exude

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

To jest błędna biblioteka – MFARID

+0

@MFARID Czy możesz podać wyjaśnienie na jakiej podstawie jest to biblioteka błędów? –

Powiązane problemy