【问题标题】:How do truncate string of certain length but include complete words after truncation如何截断一定长度的字符串但在截断后包含完整的单词
【发布时间】:2017-02-10 02:38:08
【问题描述】:

我想从字符串中截断最多 60 个字符的子字符串,但也想在子字符串中获取完整的单词。这是我正在尝试的。

String originalText =" Bangladesh's first day of Test cricket on Indian soil has not been a good one. They end the day having conceded 71 runs in the last 10 overs, which meant they are already staring at a total of 356. M Vijay was solid and languid as he made his ninth Test century and third of the season. ";
String afterOptimized=originalText.substring(0, 60);
System.out.println("This is text . "+afterOptimized);

这是输出

This is text .  Bangladesh's first day of Test cricket on Indian soil has n

但是我的要求是不要把中间的单词删掉。我怎么知道60个字符之后有没有完整的单词。

【问题讨论】:

  • 怎么样:如果原始字符串在位置 60(第 61 个字符)有一个字符(意味着你要剪切一个单词,或者一个单词开始),从位置开始搜索并包括位置59(第 60 个字符)并在找到空格时停止。在那个位置剪断字符串。
  • @SlipperySeal 如果你有答案,写出来
  • @SlipperySeal 将管理最多 2 或 3 个字符,可以是 63 或最多 57。

标签: java arrays string


【解决方案1】:

您可以为此使用正则表达式,最多占用 60 个字符并在单词边界处结束:

Pattern pattern = Pattern.compile("(.{1,60})(\\b|$)(.*)");
Matcher m = pattern.match(originalText);
If (m.matches())
    afterOptimized = m.group(1);

或者,在一个循环中:

Pattern pattern = Pattern.compile("\\s*(.{1,60})(\\b|$)");
Matcher m = pattern.matcher(originalText);
int last = 0;
while (m.find()) {
    System.out.println(m.group(1));
    last = m.end();
}
if (last != originalText.length())
    System.out.println(originalText.substring(last));

如果您只想在空格而不是单词边界处换行(可能在逗号、点等之前换行),您可能需要将 \b 替换为 \s

【讨论】:

  • 奈斯奈斯。我在想一定有一种模式匹配的方法,确实有
  • 肯定比我的回答干净:)
  • 这对我不起作用。我以前从未在 {1,60} 中使用过正则表达式。
  • 是的,你有吗?...它打印“孟加拉国在印度土地上测试板球的第一天并不是一个好的一天。他们在过去 10 轮比赛中丢了 71 球,这结束了这一天。这意味着他们已经盯着总共 356 人。维杰在完成他的第九个测试世纪和本赛季的第三个赛季时,他表现得稳健而慵懒。”
【解决方案2】:

如果原始字符串在位置 60(第 61 个字符)有一个字符,表示您要剪切一个单词,或者一个单词正在开始,则从位置 59(第 60 个字符)开始搜索并停止,当您找个空间。然后我们可以在该位置对字符串进行子串化。如果字符串不超过 60 个字符,我们将原样返回。

public void truncateTest() {
    System.out.println(truncateTo("Bangladesh's first day of Test cricket on Indian soil has not been a good one. They end the day having conceded 71 runs in the last 10 overs, which meant they are already staring at a total of 356. M Vijay was solid and languid as he made his ninth Test century and third of the season. ", 60));
    System.out.println(truncateTo("Bangladesh's first day.", 60));
    System.out.println(truncateTo("They end the day having conceded 71 runs in the last 10 overs, which meant they are already staring at a total of 356. M Vijay was solid and languid as he made his ninth Test century and third of the season.", 60));
}

public String truncateTo(String originalText, int len) {
    if (originalText.length() > len) {
        if (originalText.charAt(len) != ' ') {
            for (int x=len-1;x>=0;x--) {
                if (Character.isWhitespace(originalText.charAt(x))) {
                    return originalText.substring(0, x);
                }
            }
        }
        // default if none of the conditions are met
        return originalText.substring(0, len);
    }
    return originalText;
}

结果...

Bangladesh's first day of Test cricket on Indian soil has
Bangladesh's first day.
They end the day having conceded 71 runs in the last 10

我认为我的 +1 / -1 索引逻辑是正确的 :)

总结印度的击球,Pujara 是耐心的缩影,Vijay 的投篮令人蔑视,队长 Kohli 以完全不屑的方式结束了比赛,结果证明印度队完全控制了比赛。

【讨论】:

  • 太复杂了
  • @NickZiebert 是的,我同意。正要问你是否有更好的主意,你有 :) 让我称我为“教具”(什么不该做 :)
  • @NickZiebert 我想你想要一个 lastIndexOf 在那里的某个地方 - 但它应该根本不处理任何空格
【解决方案3】:

String originalText=" 孟加拉国在印度土地上测试板球的第一天并不是一个好日子。他们在过去 10 轮比赛中丢了 71 球,这意味着他们已经盯着总共 356 球。M Vijay 在他的第九个测试世纪和本赛季的第三个赛季中表现稳定而慵懒。”;

//trim the string to 60 characters

String  trimmedString = originalText.substring(0, 60);

//re-trim if we are in the middle of a word and to get full word instead of brolken one

String result=trimmedString.substring(0, Math.min(trimmedString.length(), trimmedString.lastIndexOf(" ")));

System.out.println(result);

【讨论】:

    【解决方案4】:
     int cutoff = originalText.substring(0,60).lastIndexOf(" ");
     String afterOptimized = originalText.substring(0, cutoff);
    

    代码打印如下:“Bangladesh's first day of Test cricket on Indian soil has”

    【讨论】:

      【解决方案5】:

      假设您的文本在两个单词之间有空格,只需剪切文本并检查 char 的结尾 + 在 end char 之前 + 在 end char 之后以确定我们需要剪切的内容:

      if (char[i] != ' ') {
          if(i+1 == length || (i+1 < length && char[i+1] == ' '))
               return mString; // [I'm loser] bla ==> [I'm loser]
          if(i-1 > -1 && char[i-1] == ' ')
               return subHeadString(mString, 2); // return mString which has length = length - 2, ex: [I'm loser b]la ==> [I'm loser]
          return findBackStringWithSpace(mString, i); // coming back until has space char and return that sub string 
      // [I'm loser bl]a ==> [I'm loser] 
      } else {
          return mString;
      }
      

      【讨论】:

      • 最好为downvote提供评论,以便改进/纠正答案。
      猜你喜欢
      • 2011-10-02
      • 2019-01-03
      • 2020-04-13
      • 2018-03-04
      • 2022-07-05
      • 1970-01-01
      • 2021-05-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多