计算 Java 字符串中的行数
Posted
技术标签:
【中文标题】计算 Java 字符串中的行数【英文标题】:Count the number of lines in a Java String 【发布时间】:2011-02-20 11:14:03 【问题描述】:需要一些紧凑的代码来计算 Java 中字符串的行数。字符串由\r
或\n
分隔。这些换行符的每个实例都将被视为单独的行。比如——
"Hello\nWorld\nThis\nIs\t"
应该返回4。原型是
private static int countLines(String str) ...
有人可以提供一组简洁的陈述吗?我在这里有一个解决方案,但我认为它太长了。谢谢。
【问题讨论】:
如果字符串以换行符结尾会发生什么?你会把它算作另一条线吗?那么,“foo\nbar\n”是两行还是三行? JDK/11 的另一种方式是使用String.lines()
API。
【参考方案1】:
对于 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
【讨论】:
【参考方案2】://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;
如果最后一行不以 cr/lf cr lf 结尾,这将计算最后一行
【讨论】:
【参考方案3】:如果您使用 Java 8,那么:
long lines = stringWithNewlines.chars().filter(x -> x == '\n').count() + 1;
(最后+1是如果字符串被修剪,则计算最后一行)
一线解决方案
【讨论】:
很好,但你只为\r
做了什么?
在 android 上,这需要 API 24 - 这对大多数人来说是行不通的【参考方案4】:
我正在使用:
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
【讨论】:
【参考方案5】:试试这个:
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
你好 :)
【讨论】:
【参考方案6】:此方法将分配一个字符数组,应该使用它而不是遍历 string.length() 因为 length() 使用 Unicode 字符数而不是字符数。
int countChars(String str, char chr)
char[] charArray = str.toCharArray();
int count = 0;
for(char cur : charArray)
if(cur==chr) count++;
return count;
【讨论】:
【参考方案7】:这个怎么样:
String yourInput = "...";
Matcher m = Pattern.compile("\r\n|\r|\n").matcher(yourInput);
int lines = 1;
while (m.find())
lines ++;
这样你就不需要把String拆分成很多新的String对象了,后面会被垃圾回收器清理掉。 (使用String.split(String);
时会发生这种情况。
【讨论】:
应该在这里将行初始化为0还是1? 到 1,因为在第 1 行之后找到的第一个换行符。 正确的正则表达式应该是 (\r\n)|(\n)|(\r) 否则此代码为“First\r\nSecond”返回 3 而不是 2,因为它匹配 \r和 \n 在匹配之前 \r\n. 谢谢!!!!这个我找了很久,终于找到了。工作得很好。 优化建议:预编译模式一次:private static final Pattern EOL_PATTERN=Pattern.compile("...");方法之外。并在方法中使用:Matcher m =EOL_PATTERN.matcher(yourinput);【参考方案8】:不创建字符串对象、数组或其他(复杂)对象的非常简单的解决方案是使用以下内容:
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;
请注意,如果您使用其他 EOL 终结器,则需要稍微修改此示例。
【讨论】:
【参考方案9】:"Hello\nWorld\nthis\nIs\t".split("[\n\r]").length
你也可以
"Hello\nWorld\nthis\nis".split(System.getProperty("line.separator")).length
使用系统默认的行分隔符。
【讨论】:
如果它可以正确处理文件,那么它就是System.getProperty ("line.separator");
。但我认为情况并非如此,您之前的(编辑前)解决方案是正确的。【参考方案10】:
如果文件中的行已经在字符串中,则可以这样做:
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;
【讨论】:
该行不是来自文件,它只是一个字符串。但这是一个不错的代码 FileUtils.readFileToString(file) 参数不应该是 java.io.File 实例吗,您上面的代码正在传递一个字符串(我使用的是 Commons-io 2.4)? @BigRich - 是的,你是对的。谢谢指出,我更正了代码。 如果您在 Windows 上创建文件并且您的 JVM 在 linux 操作系统上,则此代码将不起作用,反之亦然。如果你可以假设文件是你运行 jvm 的操作系统的格式,那没关系。 @autra - 这更像是一般类型的问题。在尝试解析文件之前,您应该修复适用于给定操作系统的行尾。或者,如果您知道文件是 Windows 格式(例如,您知道行尾类型),您也可以为此编写代码。我真的不认为这是对我的答案投反对票的理由,但你有权发表你的意见。【参考方案11】:这是一个更快的版本:
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;
【讨论】:
【参考方案12】:new StringTokenizer(str, "\r\n").countTokens();
请注意,这不会计算空行 (\n\n)。
CRLF (\r\n) 计为单行换行符。
【讨论】:
【参考方案13】:嗯,这是一个不使用“魔法”正则表达式或其他复杂 sdk 功能的解决方案。
显然,正则表达式匹配器可能更适合在现实生活中使用,因为它的编写速度更快。 (而且它可能也没有错误......)
另一方面,你应该能够理解这里发生了什么......
如果您想将案例 \r\n 作为单个换行符 (msdos-convention) 处理,您必须添加自己的代码。提示,您需要另一个变量来跟踪匹配的前一个字符...
int lines= 1;
for( int pos = 0; pos < yourInput.length(); pos++)
char c = yourInput.charAt(pos);
if( c == "\r" || c== "\n" )
lines++;
【讨论】:
如果行被“\r\n”分隔,就像在windows平台上一样?你的方法将使行数加倍 因为这可能是作业,我刚刚在答案中提到了那个案例。你会在上面找到它...【参考方案14】:我建议你找这样的东西
String s;
s.split("\n\r");
在此处查找Java's String Split method 的说明
如果您有任何问题,请发布您的代码
【讨论】:
这不起作用,因为它只在\n\r
的序列上分裂。
是的,它不起作用。它应该是一个正则表达式。我推荐它作为一个建议而不是一个真正的实现:)【参考方案15】:
private static int countLines(String str)
String[] lines = str.split("\r\n|\r|\n");
return lines.length;
【讨论】:
虽然这对几乎所有用例都非常有用,但我只想指出,这会创建很多从未使用过的字符串 - 但仍然需要内存和 gc-ing。这可能只是在频繁使用的服务器、电话或其他东西上的问题,但它仍然是一个问题。 它的答案无效。如果您的 String 仅包含新行,则它不起作用。 @kukis 如果要包含尾随换行符,则必须为 split 的限制参数传递一个显式参数 -1(即 str.split("\r\n|\r|\n ", -1); 如果你在这里查看文档:docs.oracle.com/javase/7/docs/api/java/lang/… 它有更多信息。 一个班轮int count = text.split("\r\n|\r|\n").length;
从 java 1.1 开始就有了 LineNumberReader。请参阅下面的答案。以上是关于计算 Java 字符串中的行数的主要内容,如果未能解决你的问题,请参考以下文章