JAVA - Вставка новой строки через следующий пробел после 30 символов

StackOverflow https://stackoverflow.com/questions/1033563

  •  06-07-2019
  •  | 
  •  

Вопрос

У меня есть большой блок текста (более 200 символов в строке), и мне нужно вставить новые строки через следующий пробел после 30 символов, чтобы сохранить слова.Вот что у меня есть сейчас (НЕ работает):

String rawInfo = front.getItemInfo(name);
String info = "";
int begin = 0;
for(int l=30;(l+30)<rawInfo.length();l+=30) {
    while(rawInfo.charAt(l)!=' ')
        l++;
    info += rawInfo.substring(begin, l) + "\n";
    begin = l+1;
    if((l+30)>=(rawInfo.length()))
        info += rawInfo.substring(begin, rawInfo.length());
}

Спасибо за любую помощь

Это было полезно?

Решение

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

Поскольку я не был совсем уверен, является ли количество символов перед вставкой новой строки словом до или после 30 символов, я решил использовать слово после 30 символов, поскольку реализация, вероятно, проще.

Подход заключается в том, чтобы найти экземпляр " " который встречается по крайней мере через 30 символов после текущего символа, который просматривается с помощью StringBuilder.indexOf.Когда возникает пробел, \n вставляется с помощью StringBuilder.insert.

(Мы будем считать, что новая строка - это \n здесь - фактический разделитель строк, используемый в текущей среде, может быть получен с помощью System.getProperty("line.separator");).

Вот такой пример:

String s = "A very long string containing " +
    "many many words and characters. " +
    "Newlines will be entered at spaces.";

StringBuilder sb = new StringBuilder(s);

int i = 0;
while ((i = sb.indexOf(" ", i + 30)) != -1) {
    sb.replace(i, i + 1, "\n");
}

System.out.println(sb.toString());

Результат:

A very long string containing many
many words and characters. Newlines
will.

Я должен добавить, что приведенный выше код не был протестирован, за исключением примера String это я показал в коде.Было бы не слишком удивительно, если бы при определенных обстоятельствах это не сработало.

Редактировать

Цикл в примере кода был заменен на while цикл, а не for цикл, который был не очень уместен в этом примере.

Кроме того, StringBuilder.insert метод был заменен следующим StringBuilder.replace метод, как упоминал Кевин Стич в комментариях, что replace был использован метод, а не insert чтобы получить желаемое поведение.

Другие советы

Вот решение, основанное на тестировании.

import junit.framework.TestCase;

public class InsertLinebreaksTest extends TestCase {
    public void testEmptyString() throws Exception {
        assertEquals("", insertLinebreaks("", 5));
    }

    public void testShortString() throws Exception {
        assertEquals("abc def", insertLinebreaks("abc def", 5));
    }

    public void testLongString() throws Exception {
        assertEquals("abc\ndef\nghi", insertLinebreaks("abc def ghi", 1));
        assertEquals("abc\ndef\nghi", insertLinebreaks("abc def ghi", 2));
        assertEquals("abc\ndef\nghi", insertLinebreaks("abc def ghi", 3));
        assertEquals("abc def\nghi", insertLinebreaks("abc def ghi", 4));
        assertEquals("abc def\nghi", insertLinebreaks("abc def ghi", 5));
        assertEquals("abc def\nghi", insertLinebreaks("abc def ghi", 6));
        assertEquals("abc def\nghi", insertLinebreaks("abc def ghi", 7));
        assertEquals("abc def ghi", insertLinebreaks("abc def ghi", 8));
    }

    public static String insertLinebreaks(String s, int charsPerLine) {
        char[] chars = s.toCharArray();
        int lastLinebreak = 0;
        boolean wantLinebreak = false;
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < chars.length; i++) {
            if (wantLinebreak && chars[i] == ' ') {
                sb.append('\n');
                lastLinebreak = i;
                wantLinebreak = false;
            } else {
                sb.append(chars[i]);
            }
            if (i - lastLinebreak + 1 == charsPerLine)
                wantLinebreak = true;
        }
        return sb.toString();
    }
}

Лучшее решение: скопируйте строку в StringBuilder, чтобы вы могли вставлять / изменять символы без большого количества подстановок подстрок. Затем используйте метод indexOf (), который занимает начальную позицию, чтобы найти индекс для изменения.

Изменить: код:

public static String breakString(String str, int size)
{
    StringBuilder work = new StringBuilder(str);
    int pos = 0;
    while ((pos = work.indexOf(" ", pos + size)) >= 0)
    {
        work.setCharAt(pos, '\n');
    }
    return work.toString();
}

Я бы перебрал строку вместо 30. Вы должны отслеживать 30, хотя.

psuedocode, потому что это звучит как домашнее задание:

charInLine=0
iterateOver each char in rawString
    if(charInLine++ > 30 && currChar==' ')
        charInLine=0
        currChar='\n'

Может быть, я чего-то не понимаю.Что случилось с

Строка s = ...s = s.подстрока(0, 30) + s.подстрока(30).заменить(' ', ' ');

При этом все пробелы заменяются символами новой строки, начинающимися после символа 30.

Это немного менее эффективно, но для 200 символов это действительно не имеет значения (это чрезвычайно мало для манипулирования данными).

Брюс

    String s = "A very long string containing " +
"many many words and characters. " +
"Newlines will be entered at spaces.";
StringBuilder sb = new StringBuilder(s);
int i = 0;
while ((i = sb.indexOf(" ", i + 30)) != -1) {
    sb.replace(i, i + 1, "\n");
}
System.out.println(sb.toString());

это правильный, я тоже попробовал это.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top