Как отделить много разных слов от строки (Java) - PullRequest
0 голосов
/ 21 декабря 2018

Я пытался понять, как получить слово неизвестной длины из строки неизвестной длины, которое я читаю из файла.Слова, которые я хочу из строки, всегда отделяются "."и / или «&», где вся строка заключена в кавычки.Пример: ". Слова. Символы и цифры и буквы. Типы и опечатки."Я знаю местоположение каждого "."и "&", а также сколько раз они встречаются.

Я хочу передать слова в массив. Пример [i] [j] основан на том, разделены ли слова знаком "."или "&".Так что слова, содержащиеся между "."будет установлен в столбец i массива, а слова, соединенные символом «&» в j строках массива.

Входная строка может содержать в основном переменное количество слов.Это означает, что может быть только одно слово, представляющее интерес, или сто +.

Я бы предпочел использовать массивы для решения этой проблемы.Из того, что я прочитал, регулярное выражение будет медленным, но работать.split () также может сработать, но я думаю, что мне нужно знать, какие слова нужно искать заранее.

Из этой строки: ".Word.Characters & Numeric & Letters.Typos & Mistypes."Я ожидаю получить: (не беспокоясь о том, какая строка или столбец)

[[Word], [null], [null]],

[[Знаки], [Numbers], [Letters]],

[[Typos], [Mistypes], [null]]

Из этой строки ".Alpha.Beta.Zeta & Iota."Я ожидаю получить:

[[Alpha], [null]],

[[Beta], [null]],

[[Zeta],[Йота]]

//NumerOfPeriods tells me how many word "sections" are in the string
//Stor[] is an array that holds the string index locations of "."
for(int i=0;i<NumberOfPeriods;i++)
{
    int length = Stor[i];
    while(Line.charAt(length) != '"')
    {
        length++;
    }
    Example[i] = Line.substring(Stor[i], length);
}
//This code can get the words separated by "." but not by "&"

//Stor[] is an array that holds all string index locations of '.'
//AmpStor[] is an array that holds all string index locations of '&'
int TotalLength = Stor[0];
int InnerLength = 0;
int OuterLength = 0;
while(Line.charAt(TotalLength) != '"')
{
    while(Line.charAt(OuterLength)!='.')
    {
        while(Line.charAt(InnerLength)!='&')
        {
            InnerLength++;
        }
        if(Stor[i] > AmpStor[i])
        {
            Example[i][j] = Line.substring(Stor[i], InnerLength);
        }
        if(Stor[i] < AmpStor[i])
        {
            Example[i][j] = Line.substring(AmpStor[i],InnerLength);
        }
            OuterLength++;
    }
}
//Here I run into the issue of indexing into different parts of the array i & j

Ответы [ 3 ]

0 голосов
/ 21 декабря 2018

Если я правильно понимаю проблему, вы хотите разделить строку на подстроки, разделенные символом '.'а затем для каждой из подстрок разделите ее на подстроки, разделенные символом «&».Если это так, то я бы использовал метод split:

List<List<String>> terms = Arrays.stream(input.split("\\."))
    .map(s -> Arrays.asList(s.split("\\&"))
    .collect(Collectors.toList());

, если вам действительно нужно вернуть его в виде массива с нулевым заполнением:

String[][] result = new String[terms.size()][ terms.stream.mapToInt(List::size).max().getAsInt()];
IntStream.range(0, terms.size()).forEach(i ->
    IntStream.range(0, terms.get(i).size()).forEach(j -> 
        result[i][j] = terms.get(i).get(j)));
0 голосов
/ 21 декабря 2018

Вот как я пытался решить проблему:

import java.util.*;
import java.util.stream.*;

public class StringSplitSplits {

    private static final String S1 = ".Word.Characters&Numeric&Letters.Typos&Mistypes.";
    private static final String S2 = ".Alpha.Beta.Zeta&Iota.";

    public static void main(String [] args) {

        String str = stripStartAndEndDots(S1);
        String [] ss = str.split("\\.");
        int maxLength = getMaxLength(ss);

        String [][] sss = Stream.of(ss)
                                .map(s -> s.split("&"))
                                .map(s -> Arrays.copyOf(s, maxLength))
                                .toArray(String[][]::new);
        Stream.of(sss).forEach(s -> System.out.println(Arrays.toString(s)));
    }

    private static String stripStartAndEndDots(String input) {
        if (input.startsWith(".")) {
            input = input.substring(1);
        }
        if (input.endsWith(".")) {
            input = input.substring(0, input.length()-1);
        }
        return input;
    }

    /*
     * Get max length of the arrays split on the "&" for each
     * string element of the input string array.
     */
    private static int getMaxLength(String [] input) {
        return Stream.of(input)
                        .map(s -> s.split("&"))
                        .mapToInt(ss -> ss.length)
                        .max()
                        .orElse(0);
    }
}


Ввод: ".Word.Characters&Numeric&Letters.Typos&Mistypes."
Ввод:

[Word, null, null]
[Characters, Numeric, Letters]
[Typos, Mistypes, null]

Ввод: ".Alpha.Beta.Zeta&Iota."
Вывод:

[Alpha, null]
[Beta, null]
[Zeta, Iota]
0 голосов
/ 21 декабря 2018

Так я бы решил вашу проблему (она полностью отличается от вашего кода, но работает).

Прежде всего удалите кавычки, а также начальные и конечные символы, не являющиеся словами.Это можно сделать с помощью replaceAll:

String Formatted = Line.replaceAll( "(^\"[.&]*)|([.&]*\"$)", "" );

Регулярное выражение в первом аргументе будет соответствовать двойным кавычкам на обоих концах, а также ведущим и конечным . s и & s.Метод возвратит новую строку, в которой удаляются совпадающие символы, поскольку второй аргумент является пустой строкой (он заменяется пустой строкой).

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

String[] StringGroups = Formatted.split( "\\." );
String[][] Elements = new String[StringGroups.length][];

Используйте обратную косую черту (\\) перед точкой, чтобы указать, что он должен разделяться на . -символы, так как этот метод принимаетрегулярное выражение (и просто . разделяется на любой не-символ новой строки).

Теперь разделите каждую строку в этом массиве на каждый &, используя тот же метод split.Добавьте результат непосредственно в массив Elements:

// Loop over the array
int MaxLength = 0;
for( int i = 0; i < StringGroups.length; i ++ ) {
   String StrGroup = StringGroups[ i ];
   String[] Group = StrGroup.split( "&" );
   Elements[ i ] = Group;

   // Measure the max length
   if( Group.length > MaxLength ) {
       MaxLength = Group.length;
   }
}

A \\ не требуется для ввода, поскольку & просто соответствует & -символам.Теперь вам нужно только заполнить ваши данные в массив.Переменная MaxLength предназначена для добавления значений null в ваш массив.Если они вам не нужны, просто удалите их, и все готово.

Если вы хотите получить значения null, переберите массив элементов и скопируйте текущие строки в новые массивы:

for( int i = 0; i < Elements.length; i ++ ) {
    String[] Current = Elements[ i ];
    String[] New = new String[ MaxLength ];

    // Copy existing values into new array, extra values remain null
    System.arraycopy( Current, 0, New, 0, Current.length );
    Elements[ i ] = New;
}

Теперь массив Elements содержит именно то, что вы хотели.

Вот полный исполняемый код:

public class StringSplitterExample {
    public static void main( String[] args ) {
        test( "\".Word.Characters&Numeric&Letters.Typos&Mistypes.\"" );
        System.out.println(); // Line between
        test( "\".Alpha.Beta.Zeta&Iota.\"" );
    }

    public static void test( String Line ) {
        String Formatted = Line.replaceAll( "(^\"[.&]*)|([.&]*\"$)", "" );
        String[] StringGroups = Formatted.split( "\\." );
        String[][] Elements = new String[StringGroups.length][];

        // Loop over the array
        int MaxLength = 0;
        for( int i = 0; i < StringGroups.length; i ++ ) {
            String StrGroup = StringGroups[ i ];
            String[] Group = StrGroup.split( "&" );
            Elements[ i ] = Group;

            // Measure the max length
            if( Group.length > MaxLength ) {
                MaxLength = Group.length;
            }
        }

        for( int i = 0; i < Elements.length; i ++ ) {
            String[] Current = Elements[ i ];
            String[] New = new String[ MaxLength ];

            // Copy existing values into new array, extra values remain null
            System.arraycopy( Current, 0, New, 0, Current.length );
            Elements[ i ] = New;
        }

        for( String[] Group : Elements ) {
            for( String String : Group ) {
                System.out.print( String );
                System.out.print( " " );
            }
            System.out.println();
        }
    }
}

Вывод этого примера:

Word null null 
Characters Numeric Letters 
Typos Mistypes null 

Alpha null 
Beta null 
Zeta Iota 

Так что это работает, и вам даже не нужно знать, где находятся символы . и & в вашей строке.Java сделает это за вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...