Java 用于提取信息的正则表达式

Java 用于提取信息的正则表达式,java,regex,Java,Regex,我有一个csv文件,数据格式如下 123,"12.5","0.6","15/9/2012 12:11:19" 这些数字是: 订单号 价格 贴现率 销售日期和时间 我想从行中提取这些数据 我尝试了正则表达式: String line = "123,\"12.5\",\"0.6\",\"15/9/2012 12:11:19\""; Pattern pattern = Pattern.compile("(\\W?),\"([\\d\\.\\-]?)\",\"([\\d\\.\\-]?)\",\"

我有一个csv文件,数据格式如下

123,"12.5","0.6","15/9/2012 12:11:19"
这些数字是:

  • 订单号
  • 价格
  • 贴现率
  • 销售日期和时间
我想从行中提取这些数据

我尝试了正则表达式:

String line = "123,\"12.5\",\"0.6\",\"15/9/2012 12:11:19\"";
Pattern pattern = Pattern.compile("(\\W?),\"([\\d\\.\\-]?)\",\"([\\d\\.\\-]?)\",\"([\\W\\-\\:]?)\"");
Scanner scanner = new Scanner(line);
if(scanner.hasNext(pattern)) {
    ...
}else{
    // Alaways goes to here
}
看起来我的模式不正确,因为它总是转到else部分。我做错了什么?有人能提出解决办法吗


非常感谢。

特别拆分似乎有点过于复杂,您应该尝试使用元素之间最明显的公共分隔符进行拆分,即逗号。也许你应该试试这样:

    final String info = "123,\"12.5\",\"0.6\",\"15/9/2012 12:11:19\"";
    final String[] split = info.split(",");
    final int orderNumber = Integer.parseInt(split[0]);
    final double price = Double.parseDouble(split[1].replace("\"", ""));
    final double discountRate = Double.parseDouble(split[2].replace("\"", ""));
    final String date = split[3].replace("\"", "");

在正则表达式中表示“零或一次出现”。您可能想改用
+
(一个或多个),这样它就可以捕获所有的数字、点、冒号等。

正则表达式对于这类工作来说非常麻烦

我建议使用CSV库,例如

库可以将
String
条目解析为
String
数组,并且可以根据需要解析单个条目。以下是针对特定问题的OpenCSV示例:

CSVReader reader = new CSVReader(new FileReader("yourfile.csv"));
String [] nextLine;
while ((nextLine = reader.readNext()) != null) {
   int orderNumber = Integer.parseInt(nextLine[0]);
   double price = Double.parseDouble(nextLine[1]);
   double discountRate = Double.parseDouble(nextLine[2]);
   ...
}
完整的文档和示例可以在scanner.hasNext(模式)

如果下一个完整标记与指定模式匹配,则返回true

但下一个标记是
123,“12.5”,“0.6”,“15/9/2012
,因为扫描器使用空格标记单词

你的正则表达式也没有什么问题

  • 您使用了
    ,意思是零或一,您应该使用
    *
    -零或多,或
    +
    -一或多
  • 您在开始时使用了
    \\W
    ,但这也将排除数字

如果您真的想使用scanner和regex,请尝试使用

Pattern.compile("(\\d+),\"([^\"]+)\",\"([^\"]+)\",\"([^\"]+)\"");
并将使用的分隔符更改为带有

scanner.useDelimiter(System.lineSeparator());

这是一种可能的解决方案:

    String line = "123,\"12.5\",\"0.6\",\"15/9/2012 12:11:19\"";
    Pattern pattern = Pattern.compile("([0-9]+),\\\"([0-9.]+)\\\",\\\"([0-9.]+)\\\",\\\"([0-9/:\\s]+)\\\"");
    Scanner scanner = new Scanner(line);
    scanner.useDelimiter("\n");
    if(scanner.hasNext(pattern)) {
        MatchResult result = scanner.match();
        System.out.println("1st: " + result.group(1));
        System.out.println("2nd: " + result.group(2));
        System.out.println("3rd: " + result.group(3));
        System.out.println("4th: " + result.group(4));
    }else{
        System.out.println("There");
    }
请注意,
表示0或1次出现,同时
+
表示1次或更多

请注意对数字使用
0-9
。如果愿意,也可以使用
\d
。对于空格,必须使用
scanner更改扫描仪的分隔符。例如,使用分隔符(\n”)

此代码段的输出为:

1st: 123
2nd: 12.5
3rd: 0.6
4th: 15/9/2012 12:11:19

你试过用逗号拆分并去掉双引号吗?这是一个正确的选择,但不是OP要问的。OP要问他的正则表达式失败的原因和一个可能的解决方案。@FèlixGalindoAllué他的正则表达式失败了,因为他试图将他想要完成的事情过度复杂化。如果我要更正正则表达式举例来说,它只会助长这种“滥用”使用特定的正则表达式来处理如此简单的事情。同时,我在回答OP的问题:“有人能为这个问题提出一个解决方案吗?”