【问题标题】:Java String Segmentation at nth position第 n 个位置的 Java 字符串分段
【发布时间】:2018-12-23 00:27:57
【问题描述】:

我在 java 中的代码和我有一个很长的文本(最多 500 个字符),我想对此文本进行一种分段,并且在每个段中我只需要 6 个字符 例如: 这是一个示例文本:

String fullText = "Syria officially known as the Syrian Arab Republic, is a country in Western Asia...";

我想要这个结果:

segment1:叙利亚

segment2:官方

Segment3: 盟友 k

第n段:……

我尝试过使用 for 循环,但我没有达到我的目标.. 而且我有一个错误

java.lang.StringIndexOutOfBoundsException: length=67; regionStart=65; regionLength=5

这是我的代码:

    String msg = fullText;

for(int i=-1 ; i <= fullText.length()+1; i++){
            
     int len = msg.length();
     text = new StringBuilder().append(msgInfo).append(msg.substring(i, i + 6)).toString();
     
     msg = new StringBuilder().append(msg.substring(i +5, len)).toString();

     LogHelper.d(TAG, "teeeeeeeeeeeeext:"+i +" .."+ text);

        }

我怎样才能正确地进行这种分割? 谢谢!

【问题讨论】:

  • 在提取最后一段时,确保只提取可用长度
  • 我对 StringBuilder 的东西感到困惑,似乎是多余的,并且可能会破坏,因为您正在获取 msg 的子字符串,然后稍后更改 msg。你只是想要一个段数组还是什么?
  • @obermillerk 是的,只需进行细分并在每个细分的开头添加一些价值
  • @emaillenin 是的,我的原始代码中有 if 条件 // if(fulltext.lenght >0)...
  • 所以你的最终目标是让原始字符串每隔 x 个字符插入一些文本?

标签: java


【解决方案1】:

你走在正确的轨道上,但你把事情复杂化了。

试试这样的

int segmentSize = 6;
String[] segments = new String[msg.length() / segmentSize + 1];

for (int i = 0; i < msg.length(); i += segmentSize) {
    // ensure we don't try to access out of bounds indexes
    int lastIndex = Math.min(msg.length(), i+segmentSize);
    int segmentNumber = i/segmentSize;
    segments[segmentNumber] = msg.substring(i, lastIndex);
}

这会将段放入该名称的数组中。 Math.min(msg.length(), i+segmentSize) 确保您不会尝试将字符拉到字符串末尾之外,这就是导致您提到的 StringIndexOutOfBounds 错误的原因。

如果你愿意,你可以做其他事情而不是将它们放入数组中。如果您的最终目标是让一些更长的字符串包含这些段,我会在 for 循环之外创建一个 StringBuilder (比如声明段数组的位置),然后您可以根据需要在循环内附加到该字符串并访问结果在循环之后(即sb.toString()),无需在每次循环迭代时创建新的 StringBuilder 实例。

【讨论】:

    【解决方案2】:

    这是一个使用 Java8 流的简洁实现:

    String fullText = "Syria officially known as the Syrian Arab Republic, is a country in Western Asia...";
    final AtomicInteger counter = new AtomicInteger(0);
    Collection<String> strings = fullText.chars()
                                        .mapToObj(i -> String.valueOf((char)i) )
                                        .collect(Collectors.groupingBy(it -> counter.getAndIncrement() / 6
                                                                    ,Collectors.joining()))
                                        .values();
    

    输出:

    [Syria , offici, ally k, nown a, s the , Syrian,  Arab , Republ, ic, is,  a cou, ntry i, n West, ern As, ia...]
    

    【讨论】:

    • 这是有用的答案。我们可以用它来划分每个单词或2个单词的字符串吗?
    • 一个简洁的答案,但我再说一遍,如果不花一些时间深入研究并查看正在发生的事情,我还不清楚这是做什么的。
    • 如果您了解流,您会发现只需阅读它就会很容易理解。
    【解决方案3】:

    你也可以使用正则表达式分割第n个字符,每6个字符精确分割

    String s ="anldhhdhdhhdhdhhdhdhdhdhdhd";
    String[] str = s.split("(?<=\\G.{6})");
    System.out.println(Arrays.toString(str));
    

    输出:

    [anldhh, dhdhhd, hdhhdh, dhdhdh, dhd]
    

    【讨论】:

    • 或多或少,是的。除非您是某种正则表达式之神,否则不清楚它在做什么
    • 我觉得不清楚,你可以指定(?&lt;=\\G.{nth position})
    • 是的,但剩下的到底是什么意思?
    【解决方案4】:

    为什么不使用一个基本上以 6 为增量迭代直到剩下少于 6 个字符的 while 循环?

    我不确定你是如何使用这些段的,所以现在我只留下了类似于你给出的预期示例输出的打印语句:

    public class StringSegmenter {
    
        private static final int SEG_LENGTH = 6;
        private static final String PREFIX = "Segment%s: %s\n";
    
        public static void main(String[] args) {
            String fullText = "Syria officially known as the Syrian Arab Republic, is a country in Western Asia...";
    
            int position = 0;
            int length = fullText.length();
            int segmentationCount = 0;
    
            // Checks that remaining characters are greater than 6, then prints segment
            // If less than 6 characters remain, prints remainder and exits loop.
            while (position < length) {
                segmentationCount++;
    
                if ((length - position) < SEG_LENGTH) {
    
                    // Replace this with logging, or StringBuilder appending, etc...
                    System.out.printf(PREFIX, segmentationCount, fullText.substring(position, length - 1));
                    break;
                }
                // Replace this with logging, or StringBuilder appending, etc...
                System.out.printf(PREFIX, segmentationCount, fullText.substring(position, position + SEG_LENGTH));
                position += SEG_LENGTH;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-01
      • 1970-01-01
      • 2012-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-13
      相关资源
      最近更新 更多