在Java中删除字符串的最后n行(句子)

3
我正在寻找一种有效的方法来从字符串中删除最后n行。有效意味着-执行速度快,不会创建太多对象。因此,我希望避免使用split()。特别是因为我的字符串有时可能会有几百甚至几千行。
例如,我得到了这样一个字符串:
This is a sample code line 1.
This is a sample code line 2.

Warm Regards,
SomeUser.

我想要删除的是最后3行(一个空行,“诚挚的问候,”和“某用户。”)。请注意,内容(包括最后3行)不是固定的。
我考虑首先使用这里的解决方案计算行数:https://dev59.com/4nE85IYBdhLWcg3wSxcv#18816371,然后再次使用类似的循环到达位置为行数-n并对该位置进行子字符串处理。
但是,我在此发布此问题,以了解是否有其他更有效的方法来实现此目的。也欢迎使用基于外部库的解决方案(如Apache Commons StringUtils)。

你想避免使用 split,但是你提供的链接中,最佳答案使用了 split。也许是因为它已经被优化了?在你的程序中使用 split 真的会成为瓶颈吗? - AntonH
不,我提供的链接应该带您到用户“Veger”的答案,他没有使用split。 - kpatil
所以我说的是“最佳答案”,而不是“你的答案”。 - AntonH
4个回答

3
您可以使用String.lastIndexOf来查找最后第三个出现的 '\n' 符号,然后使用String.substring来获取结果。
     public static void main(String[] args) {
        String s = "This is a sample code line 1.\n" +
                "This is a sample code line 2.\n" +
                "\n" +
                "Warm Regards,\n" +
                "SomeUser.";

        int truncateIndex = s.length();

        for (int i = 0; i < 3; i++) {
            System.out.println(truncateIndex);
            truncateIndex = s.lastIndexOf('\n', truncateIndex - 1);
        }

        System.out.println(s.substring(0, truncateIndex));
        System.out.println("--");
    }

这段代码片段有意忽略了一些边角情况,比如输入字符串少于三行时,为了使代码简单易读。


谢谢,伙计。你的解决方案是我正在使用的方案。 - kpatil
@searchengine27 我不太理解你的意思,但是第一部分,当你说“如果在只有3个换行符的字符串中运行s.lastIndexOf('\ n',2000);,它将始终给您字符串中第一个换行符的索引。”是不正确的:"\n\n\n".lastIndexOf('\n', 2000) 返回 2 - Aivean

1
public static final String SAMPLE_TEXT = "This is a sample code line 1.\nThis is a sample code line 2.\r\n\nWarm Regards,\r\nSomeUser.";

public static void main (String[] args) throws java.lang.Exception {
    String[] lines = SAMPLE_TEXT.split("\\r?\\n"); // catches Windows newlines (\r) as well)
    for (int i = 0; i < lines.length - 3; i++) {   // lines.length - 3 to discard the last 3 lines
        System.out.println(lines[i]);
    }
}

这是一个可运行的示例:

http://ideone.com/nwaMcD


1
他明确表示不想使用String.split()。话虽如此,我无法想象他实际上有什么限制会阻止他使用它... - user3062946
没有硬性的限制。我只是有点担心split()会创建很多String对象。我的文本每个实体可能会有几千行。在最坏的情况下,我需要处理500到800个这样的实体,并且该过程本身必须确保在10分钟内完成。必须休眠10分钟,然后重新开始,并且全天候不停地执行此操作。而所有这些都将在一个非常苛刻的服务器上发生。 - kpatil

0
  @scala.annotation.tailrec
  def rmLines(in: String, nlines: Int): String =
    if (nlines == 0) {
      in
    } else {
      val lastBreakIndex = in.lastIndexOf('\n')
      if (lastBreakIndex == -1) {
        in
      } else {
        rmLines(in.substring(0, lastBreakIndex), nlines - 1)
      }
    }


-2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接