【问题标题】:Parsing CSV files using Regex in Java在 Java 中使用 Regex 解析 CSV 文件
【发布时间】:2012-09-08 21:24:37
【问题描述】:

我正在尝试创建一个程序,该程序使用正则表达式从目录中读取 CSV 文件,它解析文件的每一行并在匹配正则表达式模式后显示这些行。 例如,如果这是我的 csv 文件的第一行

1997,Ford,E350,"ac, abs, moon",3000.00

我的输出应该是

1997 Ford E350 ac, abs, moon 3000.00

我不想使用任何现有的 CSV 库。我不擅长正则表达式,我使用了我在网上找到的正则表达式,但它在我的程序中不起作用 这是我的源代码,如果有人告诉我为了使我的代码正常工作,我需要修改什么地方和内容,我将不胜感激。请解释一下。

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.regex.Pattern;
import java.util.regex.Matcher;


public class RegexParser {

private static Charset charset = Charset.forName("UTF-8");
private static CharsetDecoder decoder = charset.newDecoder();
String pattern = "\"([^\"]*)\"|(?<=,|^)([^,]*)(?=,|$)";

void regexparser( CharBuffer cb)
{ 
    Pattern linePattern = Pattern.compile(".*\r?\n");
    Pattern csvpat = Pattern.compile(pattern);
    Matcher lm = linePattern.matcher(cb);
    Matcher pm = null;

    while(lm.find())
    {   
        CharSequence cs = lm.group();
        if (pm==null)
            pm = csvpat.matcher(cs);
            else
                pm.reset(cs);
        if(pm.find())
                     {

            System.out.println( cs);
                      }
        if (lm.end() == cb.limit())
        break;

        }

    }

public static void main(String[] args) throws IOException {
    RegexParser rp = new RegexParser();
    String folder = "Desktop/sample";
    File dir = new File(folder);
    File[] files = dir.listFiles();
    for( File entry: files)
    {
        FileInputStream fin = new FileInputStream(entry);
        FileChannel channel = fin.getChannel();
        int cs = (int) channel.size();
        MappedByteBuffer mbb = channel.map(FileChannel.MapMode.READ_ONLY, 0, cs);
        CharBuffer cb = decoder.decode(mbb);
        rp.regexparser(cb);
        fin.close();

    }




}

  }

这是我的输入文件

年份、品牌、型号、描述、价格

1997,福特,E350,"ac, abs, moon",3000.00

1999,Chevy,"Venture""加长版""","",4900.00

1999,Chevy,"Venture""加长版,超大""","",5000.00

1996,吉普,大切诺基,“必须卖!

空气,月顶,装载",4799.00

我得到的输出与我的代码中的问题在哪里?为什么我的正则表达式对代码没有任何影响?

【问题讨论】:

  • “我不想使用任何现有的 CSV 库”我建议您详细说明这一点。为什么不?一般来说,Regex 是这个工作的错误工具,有很好的 CSV 解析库用于此目的。
  • String.split (docs.oracle.com/javase/1.4.2/docs/api/java/lang/String.html) 对您来说还不够吗? :)
  • @EdC 通过使用正则表达式,我试图将其扩展到其他文件格式,例如通用阅读器,通过使用不同的正则表达式,我可以解析不同的格式。顺便说一句,为什么 Regex 是错误的工具,您能详细说明一下吗?
  • @m4tx 完整的 CSV 支持比这更复杂,您必须处理引用的内容、跨多行的行和转义。
  • @niranjan-subramanian 基本上,CSV 是一种比看起来更复杂的格式,有很多边缘情况需要处理。正则表达式非常适合搜索字符串。虽然它可以用于解析,但其他工具可以更好地完成这项工作。不要说得太细,但那些 CSV 解析库是有原因的。

标签: java regex csv


【解决方案1】:

使用 regexp 似乎“花哨”,但使用 CSV 文件(至少在我看来)是不值得的。对于我的解析,我使用http://commons.apache.org/csv/。它从来没有让我失望过。 :)

【讨论】:

  • 是的,我明白,重新发明轮子不是一个好主意,但至少出于学习目的,我需要为我的程序提供解决方案,这就是我在这里提出问题的原因。:)跨度>
【解决方案2】:

反正我自己找到了解决办法,谢谢大家的建议和帮助。

这是我的初始代码

    if(pm.find()
        System.out.println( cs);

现在改成

  while(pm.find()
  {
 CharSequence css = pm.group();
 //print css
   }

我还使用了不同的正则表达式。我现在得到了想要的输出。

【讨论】:

  • 嘿,你能把正则表达式模式粘贴到这里吗?
  • \"([^\"]*)\"|(?
【解决方案3】:

你可以试试这个:[ \t]*+"[^"\r\n]*+"[ \t]*+|[^,\r\n]*+ 使用这个代码:

try {
    Pattern regex = Pattern.compile("[ \t]*+\"[^\"\r\n]*+\"[ \t]*+|[^,\r\n]*+", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE | Pattern.MULTILINE);
    Matcher matcher = regex.matcher(subjectString);
    while (matcher.find()) {
        // Do actions
    } 
} catch (PatternSyntaxException ex) {
    // Take care of errors
}

但是,是的,如果这不是一个非常关键的需求,请尝试使用已经工作的东西:)

【讨论】:

  • 我是否必须在你的模式中插入任何转义序列,如果我使用你的模式,我会得到错误的结构
【解决方案4】:

接受所提供的建议,不要使用正则表达式来解析 CSV 文件。该格式的使用方式看似复杂。

以下答案包含指向维基百科和描述 CSV 文件格式的 RFC 的链接:

【讨论】:

  • 没关系,但我只是想知道为什么我的代码不起作用,我无法破解代码中的错误部分
猜你喜欢
  • 2010-11-29
  • 2015-08-25
  • 1970-01-01
  • 2014-03-30
  • 2010-09-25
  • 2018-06-04
  • 2013-06-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多