2009-02-11 2 views
16

J'ai une chaîne java, qui a une longueur variable.Mettre du caractère dans une chaîne java pour chaque N caractères

Je dois mettre la pièce "<br>" dans la chaîne, disons chaque 10 caractères.

Par exemple ceci est ma chaîne:

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

Comment puis-je obtenir cette chaîne ?:

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

Merci

Répondre

20

Quelque chose comme:

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

fantastique! et si je ne veux pas mettre
en mots? exemple en évitant des choses comme: stackover
flux et mettre directement
à la fin du mot? – Giancarlo

+1

Alors c'est un problème beaucoup plus difficile. Une expression régulière * peut être le meilleur moyen d'y parvenir, mais vous devez énoncer les exigences * très * en premier. –

+0

une version courte de votre code avec regex dans ce post .. http: // stackoverflow.com/questions/10530102/java-parse-string-et-ajouter-line-break-every-100-caractères – mtk

32

Essayez:

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

EDIT: Les travaux ci-dessus ... la plupart du temps. J'ai joué avec et j'ai rencontré un problème: puisqu'il construit un Pattern par défaut en interne, il s'arrête sur les retours à la ligne. Pour contourner cela, vous devez l'écrire différemment.

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); 
} 

et le lecteur astucieux revenir sur un autre problème: vous devez échapper les caractères spéciaux regex (comme « $ 1 ») dans le texte de remplacement ou vous obtiendrez des résultats imprévisibles.

J'ai aussi été curieux et comparé cette version avec celle de Jon ci-dessus. Celui-ci est plus lent d'un ordre de grandeur (1000 remplacements sur un fichier de 60k ont ​​pris 4,5 secondes avec celui-ci, 400ms avec le sien). Sur les 4,5 secondes, seulement environ 0,7 secondes était en train de construire le motif. La plupart d'entre elles concernaient l'appariement/remplacement, de sorte qu'il ne s'est même pas dirigé vers ce type d'optimisation. Normalement, je préfère les solutions moins verbeuses aux choses. Après tout, plus de code = plus de bugs potentiels. Mais dans ce cas, je dois admettre que la version de Jon - qui est vraiment la mise en œuvre naïve (je veux dire que dans un bonne manière) - est nettement meilleure.

+0

Je reçois: séquence d'échappement non valide (les valides sont \ b \ t \ n \ f \ r \ » \ » \ \) pour "(. {1,10} \ s +" –

+0

Correction du problème Il aurait dû être \\ s mais j'avais supposé à tort que vous vouliez casser les limites des mots. et est beaucoup plus facile – 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"); 
} 

Vous pouvez obtenir plus efficace que cela, mais je vais laisser cela comme un exercice pour le lecteur.

+0

Manquant un paren arrière sur le premier append, sort également des limites de la chaîne –

+0

Vous devriez probablement utiliser StringBuilder pas StringBuffer. – cletus

+0

C'est le genre d'exercice que j'ai laissé au lecteur. – DJClayworth

0

Comment environ 1 méthode pour diviser la chaîne tous les caractères N:

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

Puis une autre méthode pour insérer quelque chose après chaque pièce:

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

Pour éviter les mots coupant ...

Essayez:

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 vous ne me dérange pas une dépendance à l'égard d'un third-party library et ne me dérange pas 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); 
} 

Puis:

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

Ce n » t diviser les mots à des espaces, mais la question, comme indiqué, ne demande pas de mot-wrap.

+1

En Java 8, vous pouvez utiliser 'return String.join (delim, split);' à la place de goyave. – Kapep

0

J'ai testé unitairement cette solution pour des conditions aux limites:

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; 
} 

Appel avec:

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

La méthode suivante prend trois paramètres. Le premier est le texte que vous voulez modifier. Le second paramètre est le texte que vous voulez insérer tous les n caractères. Le troisième est l'intervalle dans lequel vous voulez insérer le texte.

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; 
} 

Vous appelleriez à cette méthode comme ceci:

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

Le résultat est:

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

^Ceci est différent de votre exemple résultat parce que vous aviez un jeu avec 9 caractères au lieu de 10 en raison d'une erreur humaine;)

0

Vous pouvez utiliser l'expression régulière '..' pour faire correspondre deux remplacez-le par "$ 0" pour ajouter l'espace:

s = s.replaceAll ("..", "$ 0"); Vous pouvez également couper le résultat pour supprimer l'espace supplémentaire à la fin.

Sinon, vous pouvez ajouter une assertion négative pour éviter préanalyse ajouter l'espace à la fin de la chaîne:

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

Par exemple:

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

Sortie: 2342<br>3412<br>3421<br>34

Questions connexes