2009-06-23 3 views
3

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

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

+0

Итак, в чем вопрос? Это работает или нет? –

+0

Извините, это НЕ работает, я отредактирую вопрос –

+3

Кстати, правильная заглавная буква - «Java», а не «JAVA», но тег обычно достаточен, чтобы люди знали, какую платформу вас интересуют. – erickson

ответ

16

Как было предложено 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, Кевин Stich упоминалось в комментариях, что метод replace был использован вместо insert, чтобы получить желаемое поведение.

+0

Этот метод работал отлично, только что изменилось sb.insert (i, "\ n"); - sb.replace (i, i + 1, "\ n"); Спасибо! –

+0

@Kevin Stich: Я обновил код примера - цикл for был не очень уместным в этом примере, поэтому он был заменен циклом while. – coobird

2

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

Edit: Teh codez:

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(); 
} 
+0

Я думаю, что если вы не увеличиваете pos внутри цикла while, вы случайно замените каждое пространство \ n, в результате чего все строки после первого будут иметь одно слово. Вам нужно поднять позицию на 30 после каждой замены. – Karl

+0

более внимательно посмотрите на выражение while - it updates pos – kdgregory

1

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

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

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

Вот тест-управляемое решение.

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(); 
    } 
} 
+1

+1, добавив тест на ваш ответ - отличная и «гражданская» идея – dfa

+2

Спасибо! Мне нравится сначала писать тест кода, и, как продвигать эту практику; Я думаю, что я буду писать больше ответов таким образом. Я ценю поддержку. –

0

Возможно, что-то не хватает.Что случилось с

Строка s = ... s = s.substring (0, 30) + s.substring (30) .replace ('', '\ n');

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

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

Bruce

+1

Тогда каждое слово после 30-го символа будет в его собственной строке. –

 Смежные вопросы

  • Нет связанных вопросов^_^