【问题标题】:Parse a csv file using Regex in java with '|' as seperator在 java 中使用带有“|”的正则表达式解析 csv 文件作为分隔符
【发布时间】:2014-06-24 13:55:28
【问题描述】:

任何人都可以帮助我使用正则表达式吗? 我有一个 Java 程序,它读取 .csv 文件以将其加载到数据库中。

目前ist使用Pattern csvPattern = Pattern.compile("\\s*(\"[^\"]*\"|[^|]*)\\s*,?");

但是我用matcher = csvPattern.matcher(line); 逐行读取文件,我只得到空值。 这些文件具有以下格式(许多行,其中一些带有逗号,'|' 作为分隔符并在每行的末尾):

第一个文件的摘要:

0|ALGERIA|0| haggle. carefully final deposits detect slyly agai|
1|ARGENTINA|1|al foxes promise slyly according to the regular accounts. bold requests alon|
2|BRAZIL|1|y alongside of the pending deposits. carefully special packages are about the ironic forges. slyly special |

秒:

|Customer#000000001|IVhzIApeRb ot,c,E|15|25-989-741-2988|711.56|BUILDING|to the even, regular platelets. regular, ironic epitaphs nag e|
2|Customer#000000002|XSTf4,NCwDVaWNe6tEgvwfmRchLXak|13|23-768-687-3665|121.65|AUTOMOBILE|l accounts. blithely ironic theodolites integrate boldly: caref|
3|Customer#000000003|MG9kdTD2WBHm|1|11-719-748-3364|7498.12|AUTOMOBILE| deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov|
4|Customer#000000004|XxVSJsLAGtn|4|14-128-190-5944|2866.83|MACHINERY| requests. final, regular ideas sleep final accou|

第三个:

5|Supplier#000000005|Gcdm2rJRzl5qlTVzc|11|21-151-690-3663|-283.84|. slyly regular pinto bea|
6|Supplier#000000006|tQxuVm7s7CnK|14|24-696-997-4969|1365.79|final accounts. regular dolphins use against the furiously ironic decoys. |
7|Supplier#000000007|s,4TicNGB4uO6PaSqNBUq|23|33-990-965-2201|6820.35|s unwind silently furiously regular courts. final requests are deposits. requests wake quietly blit|
8|Supplier#000000008|9Sq4bBH2FQEmaFOocY45sRTxo6yuoG|17|27-498-742-3860|7627.85|al pinto beans. asymptotes haggl|
9|Supplier#000000009|1KhUgZegwM3ua7dsYmekYBsK|10|20-403-398-8662|5302.37|s. unusual, even requests along the furiously regular pac|

第四:

1|2|3325|771.64|, even theodolites. regular, final theodolites eat after the carefully pending foxes. furiously regular deposits sleep slyly. carefully bold realms above the ironic dependencies haggle careful|
1|2502|8076|993.49|ven ideas. quickly even packages print. pending multipliers must have to are fluff|
1|5002|3956|337.09|after the fluffily ironic deposits? blithely special dependencies integrate furiously even excuses. blithely silent theodolites could have to haggle pending, express requests; fu|
1|7502|4069|357.84|al, regular dependencies serve carefully after the quickly final pinto beans. furiously even deposits sleep quickly final, silent pinto beans. fluffily reg|

第五:

1|155190|7706|1|17|21168.23|0.04|0.02|N|O|1996-03-13|1996-02-12|1996-03-22|DELIVER IN PERSON|TRUCK|egular courts above the|
1|67310|7311|2|36|45983.16|0.09|0.06|N|O|1996-04-12|1996-02-28|1996-04-20|TAKE BACK RETURN|MAIL|ly final dependencies: slyly bold |

第六:

134823|saddle midnight thistle honeydew lime|Manufacturer#4|Brand#43|STANDARD BURNISHED BRASS|44|WRAP CAN|1857.82|ges. furiously ir|
134824|coral red indian thistle sandy|Manufacturer#5|Brand#55|PROMO BURNISHED COPPER|29|LG JAR|1858.82|final p|
134825|saddle purple orchid cornsilk medium|Manufacturer#4|Brand#44|PROMO POLISHED NICKEL|21|LG CASE|1859.82|nal accounts us|
134826|turquoise sky lime cornsilk peach|Manufacturer#1|Brand#11|SMALL BURNISHED TIN|25|SM CAN|1860.82| haggle|

第七:

0|AFRICA|lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to |
1|AMERICA|hs use ironic, even requests. s|

第八:

4|136777|O|32151.78|1995-10-11|5-LOW|Clerk#000000124|0|sits. slyly regular warthogs cajole. regular, regular theodolites acro|
5|44485|F|144659.20|1994-07-30|5-LOW|Clerk#000000925|0|quickly. bold deposits sleep slyly. packages use slyly|

(csv 是使用 TPC fpr tpc-h 的 DBGen 工具创建的,以防您想知道)

我希望您了解我的需求并能帮助我解决这个问题。非常感谢!

编辑:使用 String.split("|");'当然看起来很明显,但问题是,我正在使用的程序非常复杂,并且在各个部分都依赖于 regex.pattern 和 regex.matcher。因此,由于我对程序和 java 本身不是很熟悉,所以对我来说唯一的解决方案是使用给定的代码并将正则表达式替换为适合我的正则表达式。

EDIT2:问题是我正在尝试使用来自 OLTP-Bench 的 TPC-H 实现:https://github.com/ben-reilly/oltpbench/blob/master/src/com/oltpbenchmark/benchmarks/tpch/TPCHLoader.java#L347

有问题的行是 347。它是 TPC-H 数据库基准测试的完整实现,但没有数据生成器。所以我使用TPC提供的dbgen工具来生成csv文件。很遗憾,我无法与开发者取得联系。

【问题讨论】:

  • 您使用正则表达式而不是 String.split() 是否有原因?
  • 你有理由不只使用 CSV 解析器吗?
  • 你能解释一下拆分的哪一部分需要正则表达式吗?例如,某些工具在没有正确转义值的情况下导出 CSV 文件是很常见的,然后您就会陷入无法仅对分隔符进行直接拆分的混乱中。
  • 不抱歉。我不能,因为我真的不知道自己在做什么:(我更新了帖子

标签: java regex parsing csv


【解决方案1】:

鉴于您的来源,您可能只需用管道替换逗号,因为从 cmets 中,该模式所做的只是在分隔符上拆分字符串(双引号中的字符串除外)

例如:来自

\\s*(\"[^\"]*\"|[^,]*)\\s*,?

\\s*(\"[^\"]*\"|[^|]*)\\s*\\|?

至于你的号码异常,你需要调试你调用CSV加载器的方式。

我以前从未使用过该工具,但如果您查看第 352 行

for (int i = 0; i < types.length; ++i) {

现在看看从第 362 行开始的 switch 块:它定义了每个字段应该转换为的类型。

switch(types[i]) {
    case DOUBLE:
        prepStmt.setDouble(i+1, Double.parseDouble(field));
        break;
...

如果您没有正确指定类型,这种类型的转换可能会导致问题。

【讨论】:

  • 这是正确的想法,但有两个警告:首先,MxyL 取消了字符串中的一些转义...其次,零宽度字符串将匹配此表达式。由于您的所有样本都以管道结尾,因此我将消除最终的?。最终答案:\\s*(\"[^\"]*\"|[^|]*)\\s*\|.
  • 我把转义符放回去了,但我认为这会降低可读性。
  • 这是在 Java 中做它们的麻烦之一......如果你从第一行去掉转义,我会很好,FWIW。我只是觉得您似乎建议将转义版本更改为非转义版本令人困惑。
  • @user3332816 您的问题不再与正则表达式有关。你需要调试你的代码。
  • @dcsohl 我明白你的意思。是的,一致性会令人困惑。
【解决方案2】:

我建议使用String.split("|");。这将为您提供一个字符串数组,代表您的行周围的文本。

但是,如果您真的想使用正则表达式:

Pattern csvPattern = Pattern.compile("\\s*(\\d*)\\|(([^|]+)\\|)+");

这个应该匹配一个数字(或无),一个管道,然后是Something|的重复模式

【讨论】:

  • 感谢您的建议!可悲的是它对我不起作用。对不起,我不够清楚。我编辑了我的原始帖子。
  • 哇,这些管道之间有很多可能性。让我再看看
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-03
  • 2022-10-14
  • 1970-01-01
  • 2021-01-04
  • 1970-01-01
  • 2022-10-24
  • 2014-06-06
相关资源
最近更新 更多