0

我有一些特殊字符的字符串。目的是检索每行的 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
4

4 回答 4

5

解析 CSV 比乍一看要难得多,这就是为什么您最好的选择是使用经过精心设计和测试的库来为您完成这项工作。两个库是opencsvsupercsv以及许多其他库。看看两者并使用最适合您的要求和风格的那个。

于 2013-05-14T00:13:03.067 回答
3

描述

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

(?:^|,\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,}必须有一个逗号,后跟可选空格
  • |或者
  • $字符串的结尾
  • )关闭零断言向前看
于 2013-05-14T05:38:32.410 回答
1

尝试这个:

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 块中进行区分。你可能会找到一个更漂亮的方法。

输出:
Alpha
Beta
Gama
23-5-2013,TOM
TOTO
Julie, KameLTiti
God
timmy, tomy,tony,tini

于 2013-05-14T01:01:15.677 回答
0

有关解析 CSV 的与 Java 兼容的正则表达式,请参阅此相关答案。

它承认:

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

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

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


注意:虽然我在这里发布了这个关于我发现的“体面”正则表达式的答案,只是为了节省人们搜索的时间,但它绝不是健壮的。我仍然同意用户“fgv”的这个答案:最好使用 CSV 解析器。

于 2018-08-27T15:27:57.387 回答