【问题标题】:Using Spaces in Java Regex在 Java 正则表达式中使用空格
【发布时间】:2012-01-17 06:55:22
【问题描述】:

我在 Java 中使用正则表达式时遇到了很多空格问题。任务是拆分逗号分隔的输入字符串,如,

J,Project report,"F, G, I",1

分成包含以下内容的单独字符串:
J
项目报告
F、G、I
1
如果这是有道理的。我正在使用扫描仪来拆分字符串。我正在使用的正则表达式(和代码)是。

while (t.hasNext("([a-zA-Z0-9]| )*(\".+\")*,?")) { 
    System.out.println("t.next is : " + t.next());

...其中 t 是输入字符串的扫描器,如上所述。但这似乎永远不会求助于 true,因为没有打印任何内容。我最接近工作的方法就是简单地使用“。*”作为我的正则表达式,但这将在空格处分隔,我只需要在逗号处分隔,而不是在引号内。有人可以帮忙吗?谢谢。

【问题讨论】:

  • 必须使用正则表达式吗?它们可能不是这里工作的最佳工具
  • 不,这不是必需的,但简单地使用“,”作为分隔符是行不通的,因为 F、G 和 I 将在它们成为一个字符串的一部分时被分隔。诚然,这可能更简单,但我不知道如何处理它。

标签: java regex csv


【解决方案1】:

这可以通过正则表达式来完成,但正则表达式可能不是完成这项工作的最佳工具。您最终将得到的表达式将难以阅读/维护,并且不一定会更有效。

没有过多的细节,因为这是你的作业,不是我的,我会考虑另一种方式:

您需要一个有状态的扫描器。你有两种状态,“我在引号中间”和“我不是”。逐个字符扫描字符串,每个字符都会导致您累积未来结果、发出结果或更改状态。

如果这需要更健壮,它可能需要有更多的状态,例如。如果您还需要解析类似的内容:

a,"b\"c",d

【讨论】:

  • 不,它不需要非常健壮。这是整个文件:pastebin.com/imej2AYM 除了这些情况,我不需要担心其他任何事情。我也喜欢国家理念。
【解决方案2】:

试试这个:

(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)")

参考:Java: splitting a comma-separated string but ignoring commas in quotes

另外,http://regexpal.com/ 在测试正则表达式时是一个非常简洁和有用的工具:)

【讨论】:

  • 非常感谢您的帮助!我不敢相信我以前搜索时没有找到。这是一个很大的帮助。
【解决方案3】:

我同意强大的第三方 CSV 库是一种方法的建议。但是,这里是您可以使用Scanner 的方法。

Scanner t = new Scanner(new File("test.csv"));
t.useDelimiter(',(?=([^\"]*\"[^\"]*\")*[^\"]*$)');
while( t.hasNext() ) {
    System.out.println(t.next());
}

我使用了来自@Hristo 答案的正则表达式。

【讨论】:

  • 谢谢JRideout!第三方很好,但能够自己解决问题而不将其交给其他人来完成总是很好 - 我想了解正在发生的事情并能够了解血腥细节,以使我成为更好的程序员。但也许我不应该在那种情况下使用 Java? ;) 这个任务实际上不是我的,我是在帮助一个朋友,但这会很有帮助,谢谢!
【解决方案4】:

CSV 文件比最初看起来更复杂。例如,在德国国家,文件分隔符通常是“;”角色.....虽然我知道你的任务是使用正则表达式,但在真正解决这个问题时不要浪费你的时间。

我选择的工具是opencsv。这是一个解析字符串的 groovy 脚本(我让您将其转换为 Java):

import au.com.bytecode.opencsv.CSVParser

@Grapes([
    @Grab(group='net.sf.opencsv', module='opencsv', version='2.3')
])

CSVParser csv = new CSVParser()
String[] result = csv.parseLine('J,Project report,"F, G, I",1')

assert result[0] == "J"
assert result[1] == "Project report"
assert result[2] == "F, G, I"
assert result[3] == "1"

CSVReader 对象提供了迭代文件内容的方法:

new File("data.csv").withReader { reader ->
    CSVReader csv = new CSVReader(reader);

    csv.readAll().each {
        println it[0]
        println it[1]
        println it[2]
        println it[3]
    }
}

【讨论】:

  • 这个任务实际上并不是使用正则表达式,它甚至不是我的任务哈哈。我的朋友在他的软件工程课上需要帮助,而我无法帮助解决问题让我很困扰,因此我的线程。但请记住,这个库可能对我和我的朋友都有好处。谢谢!我几乎选择了这个回应作为答案。信息量很大!
猜你喜欢
  • 1970-01-01
  • 2013-02-26
  • 1970-01-01
  • 2019-07-07
  • 1970-01-01
  • 2014-08-10
  • 1970-01-01
  • 1970-01-01
  • 2011-08-10
相关资源
最近更新 更多