Java 8编程:读取.ini文件并试图摆脱换行符

时间:2021-09-05 22:29:32

I'm using Netbeans IDE. For a school project I need to read an .ini-file, and get some specific information.

我正在使用Netbeans IDE。对于学校项目,我需要阅读.ini文件,并获取一些具体信息。

The reason I'm not using ini4j:

我没有使用ini4j的原因:

  • I have a section that has key values which are the same
  • 我有一个具有相同键值的部分

  • I have sections that have no key-value inputs that I have to read information from
  • 我有没有键值输入的部分,我必须从中读取信息

Example ini-file:

[Section]

Object1 5 m

number = 12

Object2 6 m
;Comment followed by white line

number = 1\

4

\ means the next command or white lines need to be ignored So the last part of the ini file actually means: number = 14

\表示需要忽略下一个命令或白线所以ini文件的最后一部分实际上意味着:number = 14

My task: I need to store the oject names with the corresponding length (meters) and number into a single string like this: Object1 has length 1m and number 12

我的任务:我需要将具有相应长度(米)和数字的对象名称存储到单个字符串中,如下所示:Object1的长度为1m,数字为12

My problem: I use a scanner with delimiter //Z to store the whole file into a single String. This works (if I print out the String it gives the example above).

我的问题:我使用带分隔符// Z的扫描程序将整个文件存储到一个字符串中。这是有效的(如果我打印出它给出上面例子的String)。

I've tried this code:

我试过这段代码:

String file = file.replaceAll("(\\.)(\\\\)(\\n*)(\\.)","");

If I try to only remove the newlines:

如果我尝试仅删除换行符:

String file = file.replace("\n","");
System.out.println(file);

I get an empty output.

我得到一个空输出。

Thanks in advance !

提前致谢 !

2 个解决方案

#1


Your problem is that you need to esacpe \ in Java Strings and in regular expressions, so you need to escape them twice. This means if you want to get rid of empty lines you have to write it like this:

您的问题是您需要在Java字符串和正则表达式中使用esacpe,因此您需要将它们转义两次。这意味着如果你想摆脱空行,你必须这样写:

file = file.replaceAll("\\n+", "\n");

If you know that a \ at the end of a line is always followed by an empty line then this means that it is actually followed by 2 new line characters which would give the following:

如果你知道一行后面的\后面总是跟一个空行,那么这意味着它后面跟着2个新的行符号,它们会给出以下内容:

file = file.replaceAll("\\\\\\n\\n", "");

or (it's the same):

或者(它是一样的):

file = file.replaceAll("\\\\\\n{2}", "");

\\\\ will result in \\ in the regex, so it matches \ and \\n will become \n and match the new line character.

\\\\将在正则表达式中产生\\,因此匹配\和\\ n将变为\ n并匹配新行字符。

And as mentioned by @Bohemian it would be better to fix the ini-file. Standards make everything easier. If you insist you could use your own file extension, because it is actually another format.

正如@Bohemian所提到的,修复ini文件会更好。标准使一切更容易。如果你坚持你可以使用自己的文件扩展名,因为它实际上是另一种格式。

It is also possible to write a regular expression that directly extracts you the values:

也可以编写一个直接提取值的正则表达式:

file = file.replaceAll("\\\\\\n\\n", "");
Pattern pattern = Pattern.compile("^ *([a-zA-Z0-9_]+) *= *(.+?) *$");
Matcher matcher = pattern.matcher(file);
while (matcher.find()) {
  System.out.println(matcher.group(1)); // left side of = (already trimmed)
  System.out.println(matcher.group(2)); // right side of = (already trimmed)
}

It's easier than reading lines one by one, but performance could be worse. Anyway usually this is not an issue because ini files tend to be small.

它比逐行阅读更容易,但性能可能更差。无论如何通常这不是问题,因为ini文件往往很小。

#2


You are on right way. But logic is on wrong place. You actually need \n for your logic to recognize new value in your ini file.

你正确的方式。但逻辑错误的地方。您实际上需要\ n让您的逻辑识别您的ini文件中的新值。

I would suggest that you do not read entire file to the string. Why? You will still work with line from file one by one. Now you read whole file to string then split to single strings to analyze. Why not just read file with scanner line by line and analyze these lines as they come?

我建议你不要把整个文件读成字符串。为什么?您仍然可以逐个使用文件中的行。现在您将整个文件读取为字符串,然后拆分为单个字符串进行分析。为什么不直接用扫描仪读取文件并分析这些行呢?

And when you work with individual line then simply skip empty ones. And it solves your issue.

当你使用单独的行时,只需跳过空行。它解决了你的问题。

#1


Your problem is that you need to esacpe \ in Java Strings and in regular expressions, so you need to escape them twice. This means if you want to get rid of empty lines you have to write it like this:

您的问题是您需要在Java字符串和正则表达式中使用esacpe,因此您需要将它们转义两次。这意味着如果你想摆脱空行,你必须这样写:

file = file.replaceAll("\\n+", "\n");

If you know that a \ at the end of a line is always followed by an empty line then this means that it is actually followed by 2 new line characters which would give the following:

如果你知道一行后面的\后面总是跟一个空行,那么这意味着它后面跟着2个新的行符号,它们会给出以下内容:

file = file.replaceAll("\\\\\\n\\n", "");

or (it's the same):

或者(它是一样的):

file = file.replaceAll("\\\\\\n{2}", "");

\\\\ will result in \\ in the regex, so it matches \ and \\n will become \n and match the new line character.

\\\\将在正则表达式中产生\\,因此匹配\和\\ n将变为\ n并匹配新行字符。

And as mentioned by @Bohemian it would be better to fix the ini-file. Standards make everything easier. If you insist you could use your own file extension, because it is actually another format.

正如@Bohemian所提到的,修复ini文件会更好。标准使一切更容易。如果你坚持你可以使用自己的文件扩展名,因为它实际上是另一种格式。

It is also possible to write a regular expression that directly extracts you the values:

也可以编写一个直接提取值的正则表达式:

file = file.replaceAll("\\\\\\n\\n", "");
Pattern pattern = Pattern.compile("^ *([a-zA-Z0-9_]+) *= *(.+?) *$");
Matcher matcher = pattern.matcher(file);
while (matcher.find()) {
  System.out.println(matcher.group(1)); // left side of = (already trimmed)
  System.out.println(matcher.group(2)); // right side of = (already trimmed)
}

It's easier than reading lines one by one, but performance could be worse. Anyway usually this is not an issue because ini files tend to be small.

它比逐行阅读更容易,但性能可能更差。无论如何通常这不是问题,因为ini文件往往很小。

#2


You are on right way. But logic is on wrong place. You actually need \n for your logic to recognize new value in your ini file.

你正确的方式。但逻辑错误的地方。您实际上需要\ n让您的逻辑识别您的ini文件中的新值。

I would suggest that you do not read entire file to the string. Why? You will still work with line from file one by one. Now you read whole file to string then split to single strings to analyze. Why not just read file with scanner line by line and analyze these lines as they come?

我建议你不要把整个文件读成字符串。为什么?您仍然可以逐个使用文件中的行。现在您将整个文件读取为字符串,然后拆分为单个字符串进行分析。为什么不直接用扫描仪读取文件并分析这些行呢?

And when you work with individual line then simply skip empty ones. And it solves your issue.

当你使用单独的行时,只需跳过空行。它解决了你的问题。