Разбить строку на строку [] определенного размера - PullRequest
2 голосов
/ 15 декабря 2010

Предполагая, что моим разделителем является ',' (запятая), я ищу функцию split, которая гарантирует, что возвращаемый массив String [] имеет определенный размер (не больше, не меньше):

String[] split(String str, int limit);

split("hello", 2);               => ["hello", ""]
split("hello,", 2);              => ["hello", ""]
split(",hello", 2);              => ["", "hello"]
split("hello,world", 2);         => ["hello", "world"]
split("hello,world,goodbye", 2); => ["hello", "world,goodbye"]

Видите, как размер массива всегда равен 2?Я могу получить некоторые из этого поведения с Pattern.split, но не для каждого случая ... Как я могу это сделать?

Ответы [ 7 ]

2 голосов
/ 15 декабря 2010

Вы можете использовать Arrays.copyOf() для возврата дополненного массива. Однако заполнение будет null вместо пустой строки.

String[] parts = Arrays.copyOf("hello,".split(",", 2), 2);
String[] parts1 = Arrays.copyOf(",hello".split(",", 2), 2);
String[] parts2 = Arrays.copyOf("hello,world".split(",", 2), 2);
String[] parts3 = Arrays.copyOf("hello,world,goodbye".split(",", 2), 2);
String[] parts4 = Arrays.copyOf("hello,".split(",", 2), 4); //null padding
1 голос
/ 15 декабря 2010

StringUtils.split(string, separator, max) очень близко к тому, что вам нужно.

Тогда вы можете использовать ArrayUtils.addAll(result, emptyArray), где emptyArray - массив размером max - result.length.

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

0 голосов
/ 15 декабря 2010

Просто получить позицию разделителя и использовать подстроки довольно легко:

public static String[] split(String str, int limit){

           String[] arr = new String[limit];

           for(int i = 0; i < limit-1; i++){
               int position = str.indexOf(',');
               int length = str.length();

               if(position == -1){
                   arr[i]= str.substring(0,length);
                   str = str.substring(length, length);
               }
               else{
                   arr[i] = str.substring(0, position);
                   str = str.substring(position+1, length);
               }
            }

            arr[limit-1] = str;

            return arr;
       }
0 голосов
/ 15 декабря 2010

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

public string[] mySplit(String Split, char Delimiter, int Top)
 {
  string[] returned = new string[Top];
  for(int i = 0; i < Top; i++){
    if(i==Top)
    {
     returned[i] = Split; return;
    }
    else
    {
     int compPlace = 0;
     char comp = Split.toCharArray()[compPlace];
     while(comp != Delimiter)
     {
      compPlace++;
      comp = Split.toCharArray()[compPlace];
      }
    returned[i] = Split.SubString(0,compPlace);
    Split = Split.SubString(compPlace);
    }
  }
  return returned;
}

Я уверен, что вам придется настроить это, так как у меня небольшая головная боль на данный момент:)

0 голосов
/ 15 декабря 2010

Ну, если я вас правильно понял, вы просто хотите прекратить расщепление, как только вы достигнете счетчика, заданного аргументом, и полностью переместить оставшийся бит в последнее поле, верно? Кроме того, параметр limit должен всегда обеспечивать поле count?

Оберните метод вокруг метода Pattern.split (), который просто добавляет поля, пока не будет достигнут ваш предел / порог / минимум.

for(i=0;i<limit;++i){
 //add empty fields to array until limit is reached
}
0 голосов
/ 15 декабря 2010

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

public static String[] split(Pattern pattern, CharSequence input, int limit) {
    // perform the split
    tokens = pattern.split(input, limit);

    int tokenCount = tokens.length();
    if (tokenCount == limit) {
        // if no padding is necessary, return the result of pattern.split
        return tokens;
    } else {
        // create a new array, copy tokens into array, pad with empty string
        String[] padded = Arrays.copyOf(tokens, limit);
        for (int i = tokenCount; i < limit; i++) {
            padded[i] = "";
        }
        return padded;
    }
}

Редактировать: Обновлен для бесстыдного кражи [Arrays.copyOf] [1] из ответа нечестивца .

[1]: http://download.oracle.com/javase/6/docs/api/java/util/Arrays.html#copyOf(T[], int)

0 голосов
/ 15 декабря 2010

Я не помню весь синтаксис наизусть, но вы смотрите примерно так:

Pattern p = new Pattern("[^,]+");
String[] strings = new String[limit];
int offset = 0;
int i = 0;
for (; i < limit; i++) {
    Match m = str.match(p, offset);
    if (m == null) break;
    offset += m.string.length + 1;
    strings[i] = m.string;
}
for (; i < limit; i++) {
    strings[i] = "";
}

Опять же, это не действительный Java

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