【问题标题】:Putting char into a java string for each N characters将每 N 个字符的 char 放入一个 java 字符串中
【发布时间】:2010-10-06 22:26:35
【问题描述】:

我有一个可变长度的 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:)`

谢谢

【问题讨论】:

标签: java string char


【解决方案1】:

试试:

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”),否则您会得到不可预知的结果。

我也很好奇,并将这个版本与 Jon 的上述版本进行了基准测试。这个慢了一个数量级(60k 文件上的 1000 次替换用这个用了 4.5 秒,用他用了 400ms)。在 4.5 秒中,实际上只有大约 0.7 秒在构建模式。大部分都在匹配/替换上,所以它甚至没有导致自己进行那种优化。

我通常更喜欢不那么冗长的解决方案。毕竟,更多代码 = 更多潜在错误。但在这种情况下,我必须承认 Jon 的版本——实际上是天真的实现(我的意思是好方法)——要好得多。

【讨论】:

  • 我得到:无效的转义序列(有效的是 \b \t \n \f \r \" \' \\ ) for "(.{1,10}\s+"
  • 已修复。它应该是 \\s 但我错误地认为你想打破单词边界。你不这样,上面应该工作并且更容易。
【解决方案2】:

类似:

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

【讨论】:

  • 太棒了!如果我不想将
    放在文字中怎么办?例如避免这样的事情:stackover
    flow 并直接将
    放在单词的末尾?
  • 那么这是一个非常困难的问题。正则表达式可能是最好的方法,但您需要首先准确地说明要求非常
  • 这篇文章中带有正则表达式的代码的简短版本.. stackoverflow.com/questions/10530102/…
  • @Giancarlo 如果您不想在单词中中断,那么您可能只需运行一个简单的 for 循环并跟踪您需要插入 &lt;br&gt; 并插入的字符数如果只有当前字符是space,则它移动到第一个空格字符并插入&lt;br&gt;
  • @mtk:这个问题是 6 年前提出的。我怀疑 OP 现在已经从这个问题上移开了 :)
【解决方案3】:

您可以使用正则表达式'..'来匹配每两个字符并用“$0”替换它以添加空格:

s = s.replaceAll("..", "$0"); 您可能还想修剪结果以删除末尾的多余空间。

或者,您可以添加一个否定的前瞻断言以避免在字符串末尾添加空格:

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

例如:

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

输出:2342&lt;br&gt;3412&lt;br&gt;3421&lt;br&gt;34

【讨论】:

  • 优秀的答案
【解决方案4】:

我从String Manipulation insert a character every 4th character 来到这里,正在寻找使用 Kotlin 的 Android 解决方案。

只需添加一种使用 Kotlin 的方法(您一定会喜欢它的简单性)

val original = "123498761234"
val dashed = original.chunked(4).joinToString("-") // 1234-9876-1234

【讨论】:

    【解决方案5】:

    为了避免断字...

    试试:

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

    【讨论】:

      【解决方案6】:

      如果您不介意依赖 third-party library 并且不介意 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 );  
      

      这不会在空格处拆分单词,但如上所述,问题不要求自动换行。

      【讨论】:

      • 在 Java 8 中,您可以使用 return String.join(delim, split); 代替 guava。
      【解决方案7】:
      StringBuilder buf = new StringBuilder();
      
      for (int i = 0; i < myString.length(); i += 10) {
          buf.append(myString.substring(i, i + 10);
          buf.append("\n");
      }
      

      您可以获得比这更有效的方法,但我将把它作为练习留给读者。

      【讨论】:

      • 第一次追加时缺少尾随括号,也会超出字符串范围
      • 你应该使用 StringBuilder 而不是 StringBuffer。
      • 对于大字符串,将 StringBuffer/StringBuilder 的初始大小设置为 (myString.length()*1.1) 可能是个好主意,这样可以避免调整内部缓冲区的大小。
      • 如果 myString.length() 不能完全被 10 整除,此解决方案缺少结束括号并抛出 OutOfBoundException。我看到其他人已经提到了这一点。但是,没有人提到在循环之前评估 myString.length() 会更有效,而不是每个循环。
      【解决方案8】:

      我已经针对边界条件对该解决方案进行了单元测试:

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

      【讨论】:

        【解决方案9】:

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

        【讨论】:

          【解决方案10】:

          以下方法采用三个参数。第一个是您要修改的文本。第二个参数是您要每 n 个字符插入的文本。第三个是您要在其中插入文本的间隔。

          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:)
          

          ^这与您的示例结果不同,因为由于人为错误,您有一个包含 9 个字符而不是 10 个字符的集合;)

          【讨论】:

            【解决方案11】:

            Kotlin 正则表达式版本:

            fun main(args: Array<String>) {    
                var original = "this is my string which I need to modify...I love stackoverlow:)"
                println(original)
                val regex = Regex("(.{10})")
                original = regex.replace(original, "$1<br>")
                println(original)
            }
            

            Kotlin Playground

            【讨论】:

              【解决方案12】:
              String s = // long string
              String newString = String.join("<br>", s.split("(?<=\\G.{10})"));
              

              如果s 的长度是10 的倍数,则不添加最终的&lt;br&gt;

              感谢@cletusthis answer 的启发

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2013-03-04
                • 1970-01-01
                • 1970-01-01
                • 2015-03-13
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多