2009-02-11 15 views
16

Tengo una cadena Java, que tiene una longitud variable.Poner char en una cadena java para cada N caracteres

Necesito poner la pieza "<br>" en la cuerda, digamos cada 10 caracteres.

Por ejemplo, este es mi cadena:

`this is my string which I need to modify...I love stackoverlow:)` 

¿Cómo puedo obtener esta cadena ?:

`this is my<br> string wh<br>ich I nee<br>d to modif<br>y...I love<br> stackover<br>flow:)` 

Gracias

Respuesta

20

Algo así como:

public static String insertPeriodically(
    String text, String insert, int period) 
{ 
    StringBuilder builder = new StringBuilder(
     text.length() + insert.length() * (text.length()/period)+1); 

    int index = 0; 
    String prefix = ""; 
    while (index < text.length()) 
    { 
     // Don't put the insert in the very first iteration. 
     // This is easier than appending it *after* each substring 
     builder.append(prefix); 
     prefix = insert; 
     builder.append(text.substring(index, 
      Math.min(index + period, text.length()))); 
     index += period; 
    } 
    return builder.toString(); 
} 
+0

¡fantástico! ¿Y si no quiero poner
dentro de las palabras? ejemplo evitando cosas como: stackover
fluir y poner directamente
al final de la palabra? – Giancarlo

+1

Entonces ese es un problema significativamente más difícil. Una expresión regular * puede * ser la mejor manera allí, pero primero deberá indicar los requisitos * muy * precisamente. –

+0

una versión corta de tu código con expresiones regulares en esta publicación .. http: // stackoverflow.com/questions/10530102/java-parse-string-and-add-line-break-every-100-characters – mtk

32

Probar:

String s = // long string 
s.replaceAll("(.{10})", "$1<br>"); 

EDIT: Lo anterior funciona ... la mayoría de las veces. He estado jugando con eso y me encontré con un problema: dado que construye un patrón predeterminado internamente, se detiene en nuevas líneas. Para evitar esto, tienes que escribirlo de manera diferente.

public static String insert(String text, String insert, int period) { 
    Pattern p = Pattern.compile("(.{" + period + "})", Pattern.DOTALL); 
    Matcher m = p.matcher(text); 
    return m.replaceAll("$1" + insert); 
} 

y el lector astuto se darán cuenta de otro problema: tienes que escapar caracteres especiales de expresiones regulares (como "$ 1") en el texto de reemplazo o que obtendrá resultados imprevisibles.

También me puse curioso y comparé esta versión con la anterior de Jon. Este es más lento en un orden de magnitud (1000 reemplazos en un archivo de 60k tomaron 4.5 segundos con esto, 400ms con el suyo). De los 4.5 segundos, solo alrededor de 0.7 segundos realmente estaban construyendo el Patrón. La mayor parte estaba en la coincidencia/reemplazo por lo que ni siquiera se dirige a ese tipo de optimización.

Normalmente prefiero las soluciones menos prolijas a las cosas. Después de todo, más código = más errores potenciales. Pero en este caso debo admitir que la versión de Jon -que es realmente la implementación ingenua (quiero decir que en una buena forma ) - es significativamente mejor.

+0

estoy consiguiendo: secuencia de escape no válida (los válidos son \ b \ t \ n \ f \ r \" \' \ \) para "(. {1,10} \ s +" –

+0

Se corrigió. Debería haber sido \\ s pero había asumido erróneamente que quería romper los límites de las palabras. No debe hacerlo, lo anterior debería funcionar y es mucho más fácil. – cletus

1
StringBuilder buf = new StringBuilder(); 

for (int i = 0; i < myString.length(); i += 10) { 
    buf.append(myString.substring(i, i + 10); 
    buf.append("\n"); 
} 

usted puede obtener más eficiente que eso, pero voy a dejar que como ejercicio para el lector.

+0

Falta un paren posterior en el primer apéndice, también sale de los límites de cadena –

+0

Deberías probablemente use StringBuilder no StringBuffer. – cletus

+0

Ese es el tipo de ejercicio que dejé para el lector. – DJClayworth

0

¿Qué hay de 1 método para dividir la cadena cada N caracteres:

public static String[] split(String source, int n) 
{ 
    List<String> results = new ArrayList<String>(); 

    int start = 0; 
    int end = 10; 

    while(end < source.length) 
    { 
     results.add(source.substring(start, end); 
     start = end; 
     end += 10; 
    } 

    return results.toArray(new String[results.size()]); 
} 

A continuación, otro método para insertar algo después de cada pieza:

public static String insertAfterN(String source, int n, String toInsert) 
{ 
    StringBuilder result = new StringBuilder(); 

    for(String piece : split(source, n)) 
    { 
     result.append(piece); 
     if(piece.length == n) 
      result.append(toInsert); 
    } 

    return result.toString(); 
} 
3

Para evitar cortando las palabras ...

Probar:

int wrapLength = 10; 
    String wrapString = new String(); 

    String remainString = "The quick brown fox jumps over the lazy dog The quick brown fox jumps over the lazy dog"; 

    while(remainString.length()>wrapLength){ 
     int lastIndex = remainString.lastIndexOf(" ", wrapLength); 
     wrapString = wrapString.concat(remainString.substring(0, lastIndex)); 
     wrapString = wrapString.concat("\n"); 

     remainString = remainString.substring(lastIndex+1, remainString.length()); 
    } 

    System.out.println(wrapString); 
3

Si no te importa una dependencia de un third-party library y no les importa regexes:

import com.google.common.base.Joiner; 

/** 
* Splits a string into N pieces separated by a delimiter. 
* 
* @param text The text to split. 
* @param delim The string to inject every N pieces. 
* @param period The number of pieces (N) to split the text. 
* @return The string split into pieces delimited by delim. 
*/ 
public static String split(final String text, final String delim, final int period) { 
    final String[] split = text.split("(?<=\\G.{"+period+"})"); 
    return Joiner.on(delim).join(split); 
} 

continuación:

split("This is my string", "<br/>", 5); 

Esto no tiene' t divide las palabras en espacios, pero la pregunta, como se dijo, no solicita el ajuste de palabras.

+1

En Java 8 puede usar 'return String.join (delim, split);' en lugar de guava. – Kapep

0

he unidad a prueba esta solución para condiciones de contorno:

public String padded(String original, int interval, String separator) { 
    String formatted = ""; 

    for(int i = 0; i < original.length(); i++) { 
     if (i % interval == 0 && i > 0) { 
      formatted += separator; 
     } 
     formatted += original.substring(i, i+1); 
    } 

    return formatted; 
} 

Call con:

padded("this is my string which I need to modify...I love stackoverflow:)", 10, "<br>"); 
0

El siguiente método toma tres parámetros. El primero es el texto que desea modificar. El segundo parámetro es el texto que desea insertar cada n caracteres. El tercero es el intervalo en el que desea insertar el texto en.

private String insertEveryNCharacters(String originalText, String textToInsert, int breakInterval) { 
    String withBreaks = ""; 
    int textLength = originalText.length(); //initialize this here or in the start of the for in order to evaluate this once, not every loop 
    for (int i = breakInterval , current = 0; i <= textLength || current < textLength; current = i, i += breakInterval) { 
     if(current != 0) { //do not insert the text on the first loop 
      withBreaks += textToInsert; 
     } 
     if(i <= textLength) { //double check that text is at least long enough to go to index i without out of bounds exception 
      withBreaks += originalText.substring(current, i); 
     } else { //text left is not longer than the break interval, so go simply from current to end. 
      withBreaks += originalText.substring(current); //current to end (if text is not perfectly divisible by interval, it will still get included) 
     } 
    } 
    return withBreaks; 
} 

Se podría llamar a este método como este:

String splitText = insertEveryNCharacters("this is my string which I need to modify...I love stackoverlow:)", "<br>", 10); 

El resultado es:

this is my<br> string wh<br>ich I need<br> to modify<br>...I love <br>stackoverl<br>ow:) 

^Esto es diferente que como resultado de su ejemplo, ya que tenía un conjunto de 9 caracteres en lugar de 10 debido a un error humano;)

0

Puede usar la expresión regular '..' para que coincida con cada dos caracteres y reemplazarlo por "$ 0" para agregar el espacio:

s = s.replaceAll ("..", "$ 0"); Es posible que también desee recortar el resultado para eliminar el espacio adicional al final.

Alternativamente se puede añadir una afirmación de búsqueda negativa hacia delante para evitar añadir el espacio al final de la cadena:

s = s.replaceAll ("?! .. ($)", "$ 0");

Por ejemplo:

String s = "23423412342134"; s = s.replaceAll("....", "$0<br>"); System.out.println(s);

de salida: 2342<br>3412<br>3421<br>34

Cuestiones relacionadas