web-dev-qa-db-ja.com

文字をJava N文字ごとの文字列に入れる

Java文字列があり、可変長です。

ピースを置く必要があります"<br>"を文字列に入れ、それぞれ10文字ずつ言います。

たとえば、これは私の文字列です:

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

この文字列を取得するにはどうすればよいですか?:

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

ありがとう

26
Giancarlo

何かのようなもの:

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();
}
30
Jon Skeet

試してください:

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

編集:上記は動作します...ほとんどの場合。私はそれをいじくり回していて、問題に遭遇しました。デフォルトのパターンを内部で構築するため、改行で停止します。これを回避するには、別の方法で記述する必要があります。

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

そして鋭い読者は別の問題を取り上げます。置換テキストで正規表現の特殊文字(「$ 1」など)をエスケープする必要があります。そうしないと、予期しない結果が発生します。

また、私は好奇心が強くなり、このバージョンをジョンの上記に対してベンチマークしました。これは1桁遅いです(60kのファイルを1000回置き換えると、これで4.5秒、彼で400ミリ秒かかりました)。 4.5秒のうち、実際にパターンを構成していたのは約0.7秒だけでした。それのほとんどはマッチング/置換に関するものだったので、その種の最適化には至りませんでした。

私は通常、物事の簡潔な解決策を好みます。結局、より多くのコード=より多くの潜在的なバグ。しかし、この場合、Jonのバージョン(実際にはナイーブな実装です(つまりgood way)のほうがはるかに優れています)を認めなければなりません。

46
cletus

正規表現「..」を使用して各2文字を照合し、「$ 0」で置き換えてスペースを追加できます。

s = s.replaceAll( ".."、 "$ 0");結果をトリミングして、最後の余分なスペースを削除することもできます。

または、文字列の末尾にスペースが追加されないように、否定先読みアサーションを追加できます。

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

例えば:

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

出力:2342<br>3412<br>3421<br>34

8
Kashif Ibrahim

言葉を切り刻むのを避けるために...

試してください:

    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
Royston Bok

サードパーティライブラリ への依存を気にせず、- 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);
}

次に:

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

これはスペースで単語を分割しませんが、述べられているように、質問はワードラップを要求しません。

3
Dave Jarvis
StringBuilder buf = new StringBuilder();

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

あなたはそれよりも効率的になることができますが、それは読者のための練習として残しておきます。

1
DJClayworth

境界条件についてこのソリューションを単体テストしました。

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

次の電話番号:

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

N文字ごとに文字列を分割する1つの方法はどうでしょうか。

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

次に、各ピースの後に何かを挿入する別の方法:

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

次のメソッドは3つのパラメータを取ります。 1つ目は、変更するテキストです。 2番目のパラメーターは、n文字ごとに挿入するテキストです。 3番目は、テキストを挿入する間隔です。

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

このメソッドは次のように呼び出します。

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

結果は次のとおりです。

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

^これは、ヒューマンエラーが原因で10ではなく9文字のセットがあったため、例の結果とは異なります;)

0
Mira_Cole