在Java中计算字符串的行数

63

需要用Java编写一些简洁的代码来计算字符串中行数。该字符串将以\r\n分隔。每个换行符都将被视为单独的一行。例如 -

"Hello\nWorld\nThis\nIs\t"

应该返回4。原型是:
private static int countLines(String str) {...}

有人能提供一个简洁的语句集吗?我这里有一个解决方案,但是太长了。谢谢。


如果字符串以换行符结尾会发生什么?你会将其视为另一行吗?那么,"foo\nbar\n" 是两行还是三行? - Kartick Vaddadi
1
使用JDK/11的另一种方法是利用String.lines() API。 - Naman
16个回答

91
private static int countLines(String str){
   String[] lines = str.split("\r\n|\r|\n");
   return  lines.length;
}

38
虽然这对几乎所有的用例都非常好,但我想要指出这会创建很多从未被使用却仍需要内存和垃圾回收的字符串。这可能只在高度使用的服务器、手机或其他设备上才是一个问题,但它仍然是一个不太完美的解决方案。 - KarlP
23
这不是有效的答案。如果您的字符串仅包含换行符,则无法正常工作。 - kukis
2
@kukis 如果你想包含尾随的换行符,你必须传递一个明确的参数-1给split方法的limit参数(即str.split("\r\n|\r|\n", -1);如果你在这里查看文档:http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split%28java.lang.String,%20int%29,它有更多的信息。 - pbuchheit
值得注意的是,如果您使用Apache Commons中的StringUtils,它们的“split”版本不包括尾随换行符。即使您为长度传递负值,尾随换行符仍将被剥离。 - pbuchheit
6
一行代码:int count = text.split("\r\n|\r|\n").length; - kiedysktos
1
自Java 1.1以来,就有一个LineNumberReader。请参见我下面的答案。 - dermoritz

29

这个怎么样:

String yourInput = "...";
Matcher m = Pattern.compile("\r\n|\r|\n").matcher(yourInput);
int lines = 1;
while (m.find())
{
    lines ++;
}

这样你就不需要将字符串拆分成很多新的字符串对象,后者将稍后由垃圾回收器清理。(这发生在使用 String.split(String);时。)


这里应该将行初始化为0还是1? - skiphoppy
从第一行开始,到第一个换行符出现在第一行之后。 - Martijn Courteaux
4
正确的正则表达式应该是 (\r\n)|(\n)|(\r),否则对于 "First\r\nSecond" 这个字符串,该代码会返回 3 而不是 2,因为它在匹配 \r\n 之前先匹配了 \r 和 \n。 - Marco Ferrari
非常感谢!我已经寻找这个很长时间了,终于找到了。它完美地工作了。 - Jhonatan Sabadi
优化建议:在方法外部预编译模式:private static final Pattern EOL_PATTERN=Pattern.compile("..."); 然后在方法中使用它:Matcher m =EOL_PATTERN.matcher(yourinput); - Conffusion

27

使用Java-11及以上版本,您可以使用以下方式使用String.lines() API完成相同的操作:

String sample = "Hello\nWorld\nThis\nIs\t";
System.out.println(sample.lines().count()); // returns 4

API文档中描述如下:- 作为描述的一部分,以下内容列出:
Returns:
the stream of lines extracted from this string

22

一种非常简单的解决方案,不会创建字符串对象、数组或其他(复杂)对象,就是使用以下方法:

public static int countLines(String str) {
    if(str == null || str.isEmpty())
    {
        return 0;
    }
    int lines = 1;
    int pos = 0;
    while ((pos = str.indexOf("\n", pos) + 1) != 0) {
        lines++;
    }
    return lines;
}

请注意,如果您使用其他行尾终止符,您需要稍微修改此示例。


使用'\n'而不是"\n",并使用++lines++而不是lines++。 - undefined

13

我正在使用:

public static int countLines(String input) throws IOException {
    LineNumberReader lineNumberReader = new LineNumberReader(new StringReader(input));
    lineNumberReader.skip(Long.MAX_VALUE);
    return lineNumberReader.getLineNumber();
}

LineNumberReader位于java.io包中: https://docs.oracle.com/javase/7/docs/api/java/io/LineNumberReader.html


11

如果你已经将文件中的行保存到一个字符串中,你可以这样做:

int len = txt.split(System.getProperty("line.separator")).length;

编辑:

以防你以后需要从文件中读取内容(我知道你说你不需要,但这是为了以后参考),我建议使用Apache Commons将文件内容读入字符串中。它是一个很棒的库并且有许多其他有用的方法。这里是一个简单的例子:

import org.apache.commons.io.FileUtils;

int getNumLinesInFile(File file) {

    String content = FileUtils.readFileToString(file);
    return content.split(System.getProperty("line.separator")).length;
}

这行代码并不是来自文件,只是一个字符串。不过它还是很不错的代码。 - Simon Guo
1
FileUtils.readFileToString(file) 的参数不应该是一个字符串实例吗?你上面的代码传递的是一个字符串(我正在使用Commons-io 2.4)。 - Big Rich
@BigRich - 是的,你说得对。谢谢你指出来,我已经纠正了代码。 - dcp
如果你在Windows上创建了一个文件,而你的JVM在Linux操作系统上运行,那么这段代码将无法工作,反之亦然。如果你可以假设文件格式与你正在运行JVM的操作系统相同,那就没问题。 - autra
1
@autra - 这更像是一种通用类型的问题。在尝试解析文件之前,您应该修复行结尾以适用于给定的操作系统。或者,如果您知道文件是以Windows格式(例如,您知道行结尾类型)编码的,您也可以为此编写代码。我不认为这是贬低我的答案的理由,但您有权发表您的意见。 - dcp

10

如果您使用的是Java 8,则:

long lines = stringWithNewlines.chars().filter(x -> x == '\n').count() + 1;

(+1的作用是计算如果字符串被修剪后最后一行的字数)

一行解决方案


1
不错,但是你只针对\r做了什么? - FelixM
在安卓上,这需要API 24 - 这对大多数人来说不可行。 - slott

3
这是一个更快的版本:
public static int countLines(String str)
{
    if (str == null || str.length() == 0)
        return 0;
    int lines = 1;
    int len = str.length();
    for( int pos = 0; pos < len; pos++) {
        char c = str.charAt(pos);
        if( c == '\r' ) {
            lines++;
            if ( pos+1 < len && str.charAt(pos+1) == '\n' )
                pos++;
        } else if( c == '\n' ) {
            lines++;
        }
    }
    return lines;
}

2

Try this one:

public int countLineEndings(String str){

    str = str.replace("\r\n", "\n"); // convert windows line endings to linux format 
    str = str.replace("\r", "\n"); // convert (remaining) mac line endings to linux format

    return str.length() - str.replace("\n", "").length(); // count total line endings
}

行数 = countLineEndings(str) + 1

你好 :)


1
//import java.util.regex.Matcher;
//import java.util.regex.Pattern;

private static Pattern newlinePattern = Pattern.compile("\r\n|\r|\n");

public static int lineCount(String input) {
    Matcher m = newlinePattern.matcher(input);
    int count = 0;
    int matcherEnd = -1;
    while (m.find()) {
        matcherEnd = m.end();
        count++;
    }
    if (matcherEnd < input.length()) {
        count++;
    }

    return count;
}

如果最后一行不以回车/换行符结束,这将计算最后一行。

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