解析包含逗号和换行符的逗号分隔值

我有一些特殊字符的字符串。 目的是检索每一行的String [](,分开)你有特殊字符“你可以拥有/ n和,

For example Main String Alpha,Beta,Gama,"23-5-2013,TOM",TOTO,"Julie, KameL Titi",God," timmy, tomy,tony, tini". 

你可以看到“/”中有你/ n。

可以帮助我解决这个问题。

谢谢

__更多解释

主要刺痛我需要分开这些

 Here Alpha Beta Gama 23-5-2013,TOM TOTO Julie,KameL,Titi God timmy, tomy,tony,tini 

问题是:对于Julie,KameL,Titi有换行符/ n或
在KameL和Titi之间类似的问题对于timmy,tomy,tony,tini有断线/ n或者
介于tony和tini之间。


新的这个文本在文件中(强制逐行阅读)

 Alpha,Beta Charli,Delta,Delta Echo ,Frank George,Henry 1234-5,"Ida, John ", 25/11/1964, 15/12/1964,"40,000,000.00",0.0975,2,"King, Lincoln ",Mary / New York,123456 12543-01,"Ocean, Peter 

输出我想删除这个“

 Alpha Beta Charli Delta Delta Echo Frank George Henry 1234-5 Ida John " 25/11/1964 15/12/1964 40,000,000.00 0.0975 2 King Lincoln " Mary / New York 123456 12543-01 Ocean Peter 

尝试这个:

 String source = "Alpha,Beta,Gama,\"23-5-2013,TOM\",TOTO,\"Julie, KameL\n" + "Titi\",God,\" timmy, tomy,tony,\n" + "tini\"."; Pattern p = Pattern.compile("(([^\"][^,]*)|\"([^\"]*)\"),?"); Matcher m = p.matcher(source); while(m.find()) { if(m.group(2) != null) System.out.println( m.group(2).replace("\n", "") ); else if(m.group(3) != null) System.out.println( m.group(3).replace("\n", "") ); } 

如果它匹配没有引号的字符串,则结果在组2中返回。带引号的字符串在组3中返回。因此我需要在while块中进行区分。 你可能会找到一个更漂亮的方式。

输出:
Α
Beta版
伽马
23-5-2013,TOM
TOTO
朱莉,KameLTiti

蒂米,托米,托尼,蒂尼

解析CSV比初看起来要难得多,这就是为什么你最好的选择是使用设计良好且经过测试的库来为你完成这项工作。 两个库是opencsv和supercsv ,还有许多其他库。 看看两者并使用最适合您的要求和风格的那个。

描述

请考虑以下PowerShell示例,该示例是在Java解析器上测试的通用正则表达式,它不需要额外的处理来重新组装数据部分。 第一个匹配组将匹配报价,然后将其带到匹配结束,这样您就可以确保捕获整个值但不包括报价 。 我也不捕获逗号,除非它们嵌入了引号分隔的子字符串。

(?:^|,\s{0,})(["]?)\s{0,}((?:.|\n|\r)*?)\1(?=[,]\s{0,}|$)

 $Matches = @() $String = 'Alpha,Beta,Gama,"23-5-2013,TOM",TOTO,"Julie, KameL\n Titi",God,"timmy, \n tomy,tony,tini"' $Regex = '(?:^|,\s{0,})(["]?)\s{0,}((?:.|\n|\r)*?)\1(?=[,]\s{0,}|$)' Write-Host start with write-host $String Write-Host Write-Host found ([regex]"(?i)(?m)$Regex").matches($String) | foreach { write-host "key at $($_.Groups[1].Index) = '$($_.Groups[1].Value)'`t= value at $($_.Groups[2].Index) = '$($_.Groups[2].Value)'" } # next match 

产量

 start with Alpha,Beta,Gama,"23-5-2013,TOM",TOTO,"Julie, KameL\n Titi",God,"timmy, \n tomy,tony,tini" found key at 0 = '' = value at 0 = 'Alpha' key at 6 = '' = value at 6 = 'Beta' key at 11 = '' = value at 11 = 'Gama' key at 16 = '"' = value at 17 = '23-5-2013,TOM' key at 32 = '' = value at 32 = 'TOTO' key at 37 = '"' = value at 38 = 'Julie, KameL\n Titi' key at 60 = '' = value at 60 = 'God' key at 64 = '"' = value at 65 = 'timmy, \n tomy,tony,tini' 

概要

在此处输入图像描述

  • (?:启动非捕获组
  • ^需要字符串的开头
  • | 要么
  • ,\s{0,}逗号后跟任意数量的空格
  • )关闭非捕获组
  • (开始捕获组1
  • 如果它存在,消耗一个引用,我喜欢这样做,因为你想要包含其他字符然后引用
  • )关闭捕获组1
  • \s{0,}消耗任何空格(如果存在),这意味着您不需要稍后修剪该值
  • (开始捕获组2
  • (?:.|\n|\r)*? 捕获所有字符,包括新行,非贪心
  • )关闭捕获组2
  • \1如果有引用它将存储在组1中,所以如果有,则在此处要求它
  • (?=开始零断言向前看
  • [,]\s{0,}必须有一个逗号,后跟可选的空格
  • | 要么
  • $字符串的结尾
  • )关闭零断言outlook未来

请参阅此相关答案 ,以获得用于解析CSV的兼容Java兼容的正则表达式。

它承认:

  • 换行符(在值之后或在引用值内)
  • 包含转义双引号的引用值,例如""this""

简而言之,你将使用这种模式: (?:,|\n|^)("(?:(?:"")*[^"]*)*"|[^",\n]*|(?:\n|$))

然后在find()循环中收集每个匹配器group(1)


注意:虽然我在这里发布了一个关于我发现的“体面”正则表达式的答案,但为了节省搜索一个人的正则,它绝不是强大的。 用户“fgv”我仍然同意这个答案 :CSV Parser是首选。