【问题标题】:Parsing using Pattern in Java在 Java 中使用 Pattern 进行解析
【发布时间】:2013-05-09 18:08:47
【问题描述】:

我想使用 parsingMethod 解析文件的行

test.csv

 Frank George,Henry,Mary / New York,123456
,Beta Charli,"Delta,Delta Echo
", 25/11/1964, 15/12/1964,"40,000,000.00",0.0975,2,"King, Lincoln ",Alpha

这是我读行的方式

 public static void main(String[] args) throws Exception {


        File file = new File("C:\\Users\\test.csv");
        BufferedReader reader = new BufferedReader(new FileReader(file));   
        String line2;
        while ((line2= reader.readLine()) !=null) {
            String[] tab = parsingMethod(line2, ",");
            for (String i : tab) {
                System.out.println( i );
            }
        }


    }

    public static String[] parsingMethod(String line,String parser) {

        List<String> liste = new LinkedList<String>();
        String patternString ="(([^\"][^"+parser+ "]*)|\"([^\"]*)\")" +parser+"?";
        Pattern pattern = Pattern.compile(patternString);
        Matcher matcher =pattern.matcher(line);

        while (matcher.find()) {
            if(matcher.group(2) != null){
                liste.add(matcher.group(2).replace("\n","").trim());
            }else if(matcher.group(3) != null){
                liste.add(matcher.group(3).replace("\n","").trim());
            }       
        }

        String[] result = new String[liste.size()];
        return liste.toArray(result);
    }
}

输出:

Frank George
Henry
Mary / New York
123456

Beta Charli
Delta
Delta Echo
"
25/11/1964
15/12/1964
40,000,000.00
0.0975
2
King
Lincoln
"
Alpha
Delta
Delta Echo

我想删除这个 " , 任何人都可以帮助我改进我的模式。


预期输出

Frank George
Henry
Mary / New York
123456
Beta Charli
Delta
Delta Echo
25/11/1964
15/12/1964
40,000,000.00
0.0975
2
King
Lincoln
Alpha
Delta
Delta Echo

第 3 行的输出

25/11/1964
15/12/1964

40
000
000.00


0.0975
2

King
Lincoln

【问题讨论】:

  • 如何编译?您正在为 patternString 分配一个字符串数组。 String patternString = "(([^\"][^","]*)|\"([^\"]*)\")","?";
  • 这段代码无法编译,你有一个错误:String patternString = "(([^\"][^","]*)|\"([^\"]*)\")","?";
  • @Joan :我不擅长模式字符串。但是这段代码可以编译。我从控制台复制了输出。
  • @RicardoCacheira:我不擅长模式字符串。但是这段代码可以编译。我从控制台复制了输出
  • 正如 anana 所说,您必须对双反斜杠进行转义,但即使您这样做,程序也不会返回输出。我试过了。

标签: java regex string parsing csv


【解决方案1】:

我可以看到这些行是相关的,所以试试这个:

    public static void main(String[] args) throws Exception {

        File file = new File("C:\\Users\\test.csv");
        BufferedReader reader = new BufferedReader(new FileReader(file));
        StringBuilder line = new StringBuilder();
        String lineRead;
        while ((lineRead = reader.readLine()) != null) {
            line.append(lineRead);
        }
        String[] tab = parsingMethod(line.toString());
        for (String i : tab) {
            System.out.println(i);
        }


    }

    public static String[] parsingMethod(String line) {

        List<String> liste = new LinkedList<String>();
        String patternString = "(([^\"][^,]*)|\"([^\"]*)\"),?";
        Pattern pattern = Pattern.compile(patternString);
        Matcher matcher = pattern.matcher(line);

        while (matcher.find()) {
            if (matcher.group(2) != null) {
                liste.add(matcher.group(2).replace("\n", "").trim());
            } else if (matcher.group(3) != null) {
                liste.add(matcher.group(3).replace("\n", "").trim());
            }
        }

        String[] result = new String[liste.size()];
        return liste.toArray(result);
    }

输出:

Frank George
Henry
Mary / New York
123456
Beta Charli
Delta,Delta Echo
25/11/1964
15/12/1964
40,000,000.00
0.0975
2
King, Lincoln
Alpha

作为 Delta,Delta Echo 在引用中,这应该出现在同一行!就像林肯国王一样

【讨论】:

  • 你的 PatternString 和我的 PatternString 是相同的。仅当您将文件内容视为字符串时,这才是输出。您必须逐行读取文件并将其发送到 parserMethod。
  • 对不起,伙计,但您告诉我第 3 行开头的引号与第 2 行开始的引号接近,所以它告诉我这些行是相关的。如果不是你不知道你想要什么!!!
  • 是的,第 3 行的开头 id 接近从第 2 行开始的报价。但它是第 3 行,我必须分别解析每一行。这就是为什么我阅读每一行并使用解析它方法。抱歉不清楚。希望现在您能理解并帮助我解决这个问题。
  • 这对我来说没有意义,但是好吧!只是为了有意义,你能说出那条线是什么以及你想做什么吗?我会尽力提供帮助
  • test.csv 中产生了什么行?
【解决方案2】:

我无法重现您的结果,但我想您可能想将引号从第二个捕获的组中删除,如下所示:

"(([^\"][^"+parser+ "]*)|\"([^\"]*))\"" +parser+"?"

编辑:抱歉,这行不通。或许你也想让任意数量的^\" 在第一组中,像这样:(([^,\"]*)|\"([^\"]*)\"),?

【讨论】:

  • 对不起,我不明白你在说什么。如果我的解决方案不起作用,我相信其他人会费心把它喂给你。
  • 我请求您检查我的代码。使用我的代码中的模式字符串,我无法解析“。我也想删除”。使用您的 PatternString 我的输出就像 , , ,000.00 ,
  • 问题是我无法重现您的结果。你能在 line3 传递给 parserMethod 时输出它吗?如果你把它改成这个(([^,\"]*)|\"([^\"]*)\"),? 呢?
  • 这对我来说毫无意义。尝试输出第 3 行,以便我重现您的结果。
  • 我不是指输出,而是输入,作为 parseMethod() 的参数给出的字符串。
【解决方案3】:

您的代码没有正确编译,但这是由于某些 " 没有被转义造成的。

但这应该可以解决问题:

String patternString = "(?:^.,|)([^\"]*?|\".*?\")(?:,|$)";
Pattern pattern = Pattern.compile(patternString, Pattern.MULTILINE);

(?:^.,|) 是一个非捕获组,匹配行首的单个字符

([^\"]*?|\".*?\") 是一个捕获组,它可以匹配除“或”之间的任何内容之外的所有内容

(?:,|$) 是匹配行尾或逗号的非捕获组。

注意:^$ 仅在使用 Pattern.MULTILINE 标志编译模式时按规定工作

【讨论】:

  • 我不在模式中。现在我已经更正了我的代码()见问题。我把你的 PatternString 放在我的代码中。它给了我错误`java.lang.IndexOutOfBoundsException: No group 2`
  • 此模式一次返回一个组,因此没有第 2 组。检查是否有组要签出matcher.groupCount()
  • 如果你真的想有多个组使用这个:String patternString = "(?:(?:^.,|)([^\"]*?|\".*?\")(?:,|$))+";(我没有测试这个但我应该工作)
  • @B8rede : 不工作同样的错误 java.lang.IndexOutOfBoundsException: 没有组 2
  • 使用 if(matcher.groupCount() &gt;= 2){ liste.add(matcher.group(2).replace("\n","").trim()); }else if(matcher.groupCount() &gt;= 3){ liste.add(matcher.group(3).replace("\n","").trim()); } 它将检查是否有组 2 以及是否存在使用它。 3 相同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-03
  • 1970-01-01
  • 2014-09-08
  • 2011-06-05
  • 1970-01-01
  • 2014-10-06
  • 1970-01-01
相关资源
最近更新 更多