JAVA - Вставка новой строки через следующий пробел после 30 символов
Вопрос
У меня есть большой блок текста (более 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());
это правильный, я тоже попробовал это.