Преобразуване на низ от изречения в низов масив от думи в Java

Имам нужда от моята Java програма, за да вземе низ като:

"This is a sample sentence."

и го превърнете в низов масив като:

{"this","is","a","sample","sentence"}

Без точки или препинателни знаци (за предпочитане). Между другото, въвеждането на низ винаги е едно изречение.

Има ли лесен начин да направите това, който не виждам? Или наистина трябва да търсим много интервали и да създаваме нови низове от областите между интервалите (които са думи)?


person AnimatedRNG    schedule 12.01.2011    source източник
comment
Може също да искате да разгледате класа на guava Splitter: guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/   -  person dkarp    schedule 13.01.2011


Отговори (17)


String.split( ) ще направи повечето от това, което искате. След това може да се наложи да преминете през думите, за да извадите препинателните знаци.

Например:

String s = "This is a sample sentence.";
String[] words = s.split("\\s+");
for (int i = 0; i < words.length; i++) {
    // You may want to check for a non-word character before blindly
    // performing a replacement
    // It may also be necessary to adjust the character class
    words[i] = words[i].replaceAll("[^\\w]", "");
}
person Adam Batkin    schedule 12.01.2011
comment
Бихте ли добавили обяснение за регулярния израз, който сте използвали? - person Marek; 19.06.2013
comment
@Marek 1. \\s означава интервал, \\s+ означава множество интервали 2. .replaceAll([^\\w], ); и .replaceAll(\\W, ); И двата ще заменят знаците с изключение на [a-zA-Z0-9_]. Ако искате да замените и долната черта, използвайте: [\\W_] - person Vyshnav Ramesh Thrissur; 04.04.2018
comment
Работи добре, въпреки че имам положително гласуване, но този регулярен израз премахва всеки, ако има някакъв специален символ !!! Моля, актуализирайте, ако има нормален регулярен израз, който не премахва символи - person Tarit Ray; 26.06.2018

Сега това може да се постигне само с split, тъй като отнема регулярен израз:

String s = "This is a sample sentence with []s.";
String[] words = s.split("\\W+");

това ще даде думи като: {"this","is","a","sample","sentence", "s"}

\\W+ ще съответства на всички неазбучни знаци, които се срещат един или повече пъти. Така че няма нужда от подмяна. Можете да проверите и други модели.

person Ganapathi.D    schedule 06.04.2016
comment
Може да искате да започнете регулярния израз с (?U), за да активирате символния клас Unicode, в противен случай той ще работи само с английска азбука. - person holmis83; 05.12.2018

Можете да използвате BreakIterator.getWordInstance, за да намерите всички думи в низ.

public static List<String> getWords(String text) {
    List<String> words = new ArrayList<String>();
    BreakIterator breakIterator = BreakIterator.getWordInstance();
    breakIterator.setText(text);
    int lastIndex = breakIterator.first();
    while (BreakIterator.DONE != lastIndex) {
        int firstIndex = lastIndex;
        lastIndex = breakIterator.next();
        if (lastIndex != BreakIterator.DONE && Character.isLetterOrDigit(text.charAt(firstIndex))) {
            words.add(text.substring(firstIndex, lastIndex));
        }
    }

    return words;
}

Тест:

public static void main(String[] args) {
    System.out.println(getWords("A PT CR M0RT BOUSG SABN NTE TR/GB/(G) = RAND(MIN(XXX, YY + ABC))"));
}

Изход:

[A, PT, CR, M0RT, BOUSG, SABN, NTE, TR, GB, G, RAND, MIN, XXX, YY, ABC]
person Ninh Pham    schedule 03.11.2014
comment
не разделя x.y, т.е. смешно. Разделя ли се, връща смешно. Прави като 1 дума - person kostas.kougios; 25.09.2015
comment
И вероятно не трябва. На английски - кодът, за съжаление, не указва локал - думите не се разделят на точки. - person james.garriss; 28.10.2015

Можете също да използвате BreakIterator.getWordInstance.

person finnw    schedule 12.01.2011
comment
Еха. Документацията за това изглеждаше наистина добре. Лесен начин за намиране на думите в низа. - person AnimatedRNG; 13.01.2011

Можете просто да разделите своя низ по този начин, като използвате този регулярен израз

String l = "sofia, malgré tout aimait : la laitue et le choux !" <br/>
l.split("[[ ]*|[,]*|[\\.]*|[:]*|[/]*|[!]*|[?]*|[+]*]+");
person sofia    schedule 03.12.2013
comment
Добър за френски. Можете да добавите няколко неща като: [[ ]*|[,]*|[;]*|[:]*|[']*|[']*|[\\.]*|[:]*| [/]*|[!]*|[?]*|[+]*]+ - person blackbox; 16.12.2015

Опитайте да използвате следното:

String str = "This is a simple sentence";
String[] strgs = str.split(" ");

Това ще създаде подниз на всеки индекс на масива от низове, използвайки интервала като точка на разделяне.

person Dan Williams    schedule 15.04.2015

Най-лесният и най-добър отговор, за който мога да се сетя, е да използвам следния метод, дефиниран в низа на Java -

String[] split(String regex)

И просто направете "Това е примерно изречение".split(" "). Тъй като изисква регулярен израз, можете да правите и по-сложни разделяния, които могат да включват премахване на нежелана пунктуация и други подобни знаци.

person James    schedule 12.01.2011
comment
Момчета, това е най-простото решение, ако изречението няма препинателни знаци. - person sandalone; 21.08.2013

Използвайте string.replace(".", "").replace(",", "").replace("?", "").replace("!","").split(' '), за да разделите кода си в масив без точки, запетаи, въпросителни или удивителни знаци. Можете да добавяте/премахвате толкова заместващи повиквания, колкото искате.

person helloworld922    schedule 12.01.2011
comment
Вместо да извиквате replace 4 пъти, би било по-добре просто да го извикате веднъж с регулярен израз, който улавя всеки от 4-те елемента. - person jzd; 13.01.2011

Опитайте тази:

String[] stringArray = Pattern.compile("ian").split(
"This is a sample sentence"
.replaceAll("[^\\p{Alnum}]+", "") //this will remove all non alpha numeric chars
);

for (int j=0; i<stringArray .length; j++) {
  System.out.println(i + " \"" + stringArray [j] + "\"");
}
person MatBanik    schedule 12.01.2011

Вече публикувах този отговор някъде, ще го направя отново тук. Тази версия не използва никакъв основен вграден метод. Получихте масива char, преобразувайте го в низ. Надяваме се, че помага!

import java.util.Scanner;

public class SentenceToWord 
{
    public static int getNumberOfWords(String sentence)
    {
        int counter=0;
        for(int i=0;i<sentence.length();i++)
        {
            if(sentence.charAt(i)==' ')
            counter++;
        }
        return counter+1;
    }

    public static char[] getSubString(String sentence,int start,int end) //method to give substring, replacement of String.substring() 
    {
        int counter=0;
        char charArrayToReturn[]=new char[end-start];
        for(int i=start;i<end;i++)
        {
            charArrayToReturn[counter++]=sentence.charAt(i);
        }
        return charArrayToReturn;
    }

    public static char[][] getWordsFromString(String sentence)
    {
        int wordsCounter=0;
        int spaceIndex=0;
        int length=sentence.length();
        char wordsArray[][]=new char[getNumberOfWords(sentence)][]; 
        for(int i=0;i<length;i++)
        {
            if(sentence.charAt(i)==' ' || i+1==length)
            {
            wordsArray[wordsCounter++]=getSubString(sentence, spaceIndex,i+1); //get each word as substring
            spaceIndex=i+1; //increment space index
            }
        }
        return  wordsArray; //return the 2 dimensional char array
    }


    public static void main(String[] args) 
    {
    System.out.println("Please enter the String");
    Scanner input=new Scanner(System.in);
    String userInput=input.nextLine().trim();
    int numOfWords=getNumberOfWords(userInput);
    char words[][]=new char[numOfWords+1][];
    words=getWordsFromString(userInput);
    System.out.println("Total number of words found in the String is "+(numOfWords));
    for(int i=0;i<numOfWords;i++)
    {
        System.out.println(" ");
        for(int j=0;j<words[i].length;j++)
        {
        System.out.print(words[i][j]);//print out each char one by one
        }
    }
    }

}
person Sujal Mandal    schedule 24.08.2014

string.replaceAll() не работи правилно с локал, различен от предварително дефинирания. Поне в jdk7u10.

Този пример създава речник на думи от текстов файл с windows cyrillic charset CP1251

    public static void main (String[] args) {
    String fileName = "Tolstoy_VoinaMir.txt";
    try {
        List<String> lines = Files.readAllLines(Paths.get(fileName),
                                                Charset.forName("CP1251"));
        Set<String> words = new TreeSet<>();
        for (String s: lines ) {
            for (String w : s.split("\\s+")) {
                w = w.replaceAll("\\p{Punct}","");
                words.add(w);
            }
        }
        for (String w: words) {
            System.out.println(w);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
person corvinusz    schedule 14.01.2013

Следва кодов фрагмент, който разделя едно изречение на дума и дава също неговия брой.

 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;

 public class StringToword {
public static void main(String[] args) {
    String s="a a a A A";
    String[] splitedString=s.split(" ");
    Map m=new HashMap();
    int count=1;
    for(String s1 :splitedString){
         count=m.containsKey(s1)?count+1:1;
          m.put(s1, count);
        }
    Iterator<StringToword> itr=m.entrySet().iterator();
    while(itr.hasNext()){
        System.out.println(itr.next());         
    }
    }

}
person Eagle    schedule 14.03.2014

Друг начин да направите това е StringTokenizer. пр.:-

 public static void main(String[] args) {

    String str = "This is a sample string";
    StringTokenizer st = new StringTokenizer(str," ");
    String starr[]=new String[st.countTokens()];
    while (st.hasMoreElements()) {
        starr[i++]=st.nextElement();
    }
}
person Nikunj Gupta    schedule 10.09.2016

Можете да използвате прост следния код

String str= "This is a sample sentence.";
String[] words = str.split("[[ ]*|[//.]]");
for(int i=0;i<words.length;i++)
System.out.print(words[i]+" ");
person Rashmi singh    schedule 09.11.2017

Повечето от отговорите тук преобразуват String в String Array според зададения въпрос. Но обикновено използваме List, така че по-полезно ще бъде -

String dummy = "This is a sample sentence.";
List<String> wordList= Arrays.asList(dummy.split(" "));
person sapy    schedule 06.03.2019

Ето едно решение в обикновен и прост C++ код без фантастична функция, използвайте DMA, за да разпределите динамичен низов масив и поставете данни в масив, докато намерите свободно пространство. моля, вижте кода по-долу с коментари. Надявам се да помогне.

#include<bits/stdc++.h>
using namespace std;

int main()
{

string data="hello there how are you"; // a_size=5, char count =23
//getline(cin,data); 
int count=0; // initialize a count to count total number of spaces in string.
int len=data.length();
for (int i = 0; i < (int)data.length(); ++i)
{
    if(data[i]==' ')
    {
        ++count;
    }
}
//declare a string array +1 greater than the size 
// num of space in string.
string* str = new string[count+1];

int i, start=0;
for (int index=0; index<count+1; ++index) // index array to increment index of string array and feed data.
{   string temp="";
    for ( i = start; i <len; ++i)
    {   
        if(data[i]!=' ') //increment temp stored word till you find a space.
        {
            temp=temp+data[i];
        }else{
            start=i+1; // increment i counter to next to the space
            break;
        }
    }str[index]=temp;
}


//print data 
for (int i = 0; i < count+1; ++i)
{
    cout<<str[i]<<" ";
}

    return 0;
}
person R.singh    schedule 11.11.2019

Това трябва да помогне,

 String s = "This is a sample sentence";
 String[] words = s.split(" ");

това ще създаде масив с елементи като низ, разделен с .

person Swapnil Sharma    schedule 02.12.2020