如何从已包含双引号的文件中读取字符串?

How do I read strings from a file that already contain double quotes?

提问人:WhatTheWhat 提问时间:5/18/2022 最后编辑:WhatTheWhat 更新时间:5/18/2022 访问量:863

问:

我有一个文件中的名称列表,格式为:.txt

“蒂姆”、“戴夫”、“西蒙”

输入将始终是单值名称,用引号括起来,以逗号分隔,并在一行上。

我想把这些读进去。String[] names

我有以下代码,但输出将它们中的每一个都放在双引号中,这意味着它看起来像:

“”蒂姆“”戴夫“”西蒙“”

我也无法使用任何第三方库。

如何获得它,以便 String 数组中的每个元素只有一组双引号?

String[] names = {};

// arraylist to store strings
List<String> listOfStrings = new ArrayList<String>();

// load content of file based on specific delimiter
Scanner sc = new Scanner(new FileReader("names.txt")).useDelimiter(",");
String str;

while (sc.hasNext()) {
    str = sc.next();
    listOfStrings.add(str);
}
Java 数组 字符串 java.util.scanner 文件读取器

评论

1赞 g00se 5/18/2022
你可以做add(str.replaceAll("\\"", ""));
0赞 Dave Newton 5/18/2022
你是如何输出它们的?阅读它们不会添加引号,所以这在其他地方发生——每个元素只有一组引号。您是否在问如何删除您读入的字符串中的引号?
0赞 WhatTheWhat 5/18/2022
太好了,成功了。虽然我不需要转义字符,但还是工作了。add(str.replaceAll("\"", ""))
0赞 WhatTheWhat 5/18/2022
@DaveNewton我正在调试它们,因此可以在数组元素中看到“Tim”“等
0赞 racraman 5/18/2022
看起来您的数据是 CSV 格式,因为双引号在包含逗号的字段周围使用(但没有技术原因说明这不应该适用于所有字段)。结果是,您可以使用 CSV 库,例如 opencsv 或 Apache 的 csvreader。

答:

-1赞 g00se 5/18/2022 #1

不好意思。其实这样更好

add(s.replace("\"", ""));

评论

0赞 rzwitserloot 5/18/2022
显然,输入是CSV编码的,这实际上不起作用。例如,假设输入中有实际的引号。
1赞 g00se 5/18/2022
如果更仔细地查看代码,则不会将其视为 CSV,或者不会将其添加到一个集合中。此外,该代码设计为仅读取一行
0赞 WhatTheWhat 5/18/2022
谢谢,有没有办法直接将这些插入到一个不做String []String[] names= listOfStrings.toArray(new String[0]);
0赞 g00se 5/18/2022
如果你用逗号分割整行,你就会明白这一点。看String.split
0赞 WhatTheWhat 5/18/2022
String.split仍然给“蒂姆””
0赞 rzwitserloot 5/18/2022 #2

我有一个 .txt 文件中的名称列表,这些名称已经采用 String 格式:

他们实际上不是;这不是“字符串格式”;事实上,没有“字符串格式”这样的东西。

鉴于输入文件包含引号,并且您知道这些引号实际上不是输入的一部分,而只是分隔输入,我们可以减少对实际格式的合理猜测。事实上,只有两种常用的格式:

标准 CSV 格式

“CSV”(“字符分隔值”)是一种非常常见的数据交换格式。不幸的是,没有规范。但到目前为止,这种格式最常见的“采用”涉及以下转义规则:

  • 换行符分隔记录。
  • 某些指定的字符将单个记录中的 2 个项目分隔开来;通常是逗号、制表符或分号 - 在输入中清楚地使用逗号。
  • 所以。。如果其中一个项目从字面上看包含逗号或换行符,该怎么办?在这种情况下,通常的答案是将输入括在引号中,有时,CSV 输出工具会用引号分隔所有内容,即使不需要它(例如,大概是您的示例)。然而,这又引发了另一个问题:如果输入包含引号怎么办。然后,答案是将它们加倍。因此,文字字符串 : 成为,在 :Jane said: "Well, hello there!"example.csv
"Jane said: ""Well, hello there!"""

甚至还有一个标准:RFC 4180。这是一页纸。随意快速浏览一下。

反斜杠转义 CSV

鉴于大约 90% 的编程语言都有像这样工作的字符串常量,另一种选择是将反斜杠符号视为转义符号:反斜杠后面总是跟着一个字符,这两个字符一起告诉您基于查找表的实际意图。常见的转义是:

  • \n-> 这是一个换行符
  • \t->选项卡
  • \"->字面引用
  • \,->文字逗号

还有一些(、、、、都有些常见)。\r\f\b\123\u1234

除非此文本文件的来源告诉您它是哪种格式,或者通过获取包含此类字符串的更复杂的输入,否则根本无法知道。如果可以控制输出的实际文本,请在文本文本中使用换行符、逗号和双引号创建一个复杂的字符串,将其导出到此文本文件并查看其外观。

那么我该如何解析呢?

它非常复杂 - 正确解析这一切的代码长达许多页。不过,你很幸运!存在大量图书馆。

通常的方法是使用 OpenCSV - 这是一个教程,将带您了解如何使用它。

我只想要一根字面上的字符串Tim, Dave, Simon

好吧,这不是您的输入文件所说的;显然,您的输入文件是某种未知的格式,您将不得不解释您是如何从文本文件包含的概念到希望在单个字符串变量中得到的。也许输入确实是 CSV 格式,您只想将每个项目连接在一起,用逗号分隔。在这种情况下,请使用 OpenCSV 读取它,然后编写连接项目所需的非常简单的代码。OpenCSV 可以给你一个表示输入的“行”——把它变成一个逗号分隔的字符串,这很容易:"Tim", "Dave", "Simon"Tim, Dave, SimonList<String>

String[] csvLine = opencsv.readNext();
String output = String.join(", ", csvLine);
assert output.equals("Tim, Dave, Simon");

评论

0赞 WhatTheWhat 5/18/2022
谢谢,但输入将始终是引号中的名称,逗号分隔,我更喜欢不使用第三方库的标准库方法。我将更新我的问题以反映这一点。
0赞 rzwitserloot 5/18/2022
CSV解析是很难的,时期。java 标准库不包含 CSV 解析器。结论:这里需要第三方 deps,或者你需要接受它很复杂(即使对于一个相当有经验的程序员来说,也需要多天的编程,有很多时髦的测试输入)。“它总是在引号中”这一事实并没有使它变得更简单,问题在于输入中有换行符、逗号或引号。