7

我必须阅读包含三列的 .csv 文件。在解析 .csv 文件时,我得到了这种格式的字符串Christopher Bass,\"Cry the Beloved Country Final Essay\",cbass@cgs.k12.va.us。我想将三列的值存储在一个数组中,所以我使用了componentSeparatedByString:@","方法!它成功地向我返回了包含三个组件的数组:

  1. 克里斯托弗·巴斯
  2. 为心爱的国家哭泣期末论文
  3. cbass@cgs.k12.va.us

但是当列值中已经有逗号时,例如 Christopher Bass,\"Cry, the Beloved Country Final Essay\",cbass@cgs.k12.va.us 它将字符串分成四个部分,因为有一个 , (逗号)在 Cry 之后:

  1. 克里斯托弗·巴斯
  2. 心爱的国家期末论文
  3. cbass@cgs.k12.va.us

那么,我该如何使用正则表达式来处理这个问题。我有“RegexKitLite”类,但我应该使用哪个正则表达式。请帮忙!

谢谢-

4

5 回答 5

2

任何正则表达式都可能会出现同样的问题,您需要通过转义逗号或以这种方式突出显示字符串来清理条目或字符串:"My string". 否则你会遇到同样的问题。祝你好运。

对于您的示例,您可能需要执行以下操作:

\"Christopher Bass\",\"Cry\, the Beloved Country Final Essay\",\"cbass@cgs.k12.va.us\"

这样你就可以使用正则表达式,甚至可以使用NSString类中的相同方法。

根本不相关,但清理字符串的重要性:http: //xkcd.com/327/hehehe

于 2012-01-31T17:06:35.093 回答
1

这个怎么样:

componentsSeparatedByRegex:@",\\\"|\\\","

这应该将您的字符串拆分到任何位置并以任一顺",一起出现,从而产生一个三成员数组。这当然假设字符串中的第二个元素总是括在括号中,并且字符"永远,不会在三个组件中连续出现。

如果这些假设中的任何一个不正确,则可以使用其他方法来识别字符串组件,但应明确不存在通用解决方案。如果三个组成字符串可以包含任何地方",那么在这种情况下甚至不可能有一个有限的解决方案:

Doe, John,\"\"Why Unescaped Strings Suck\", And Other Development Horror Stories\",Doe, John <john.doe@dev.null>

希望您的 CSV 数据中没有上述内容。如果有,则数据基本上无法使用,您应该寻找更好的 CSV 导出器。

于 2012-02-09T19:22:12.983 回答
0

标题是否保证有引号?它是唯一可以拥有它们的组件吗?因为那时componentSeparatedByString:@"\""应该给你这个:

  1. 克里斯托弗·巴斯
  2. 哭泣,心爱的国家最终论文
  3. ,cbass@cgs.k12.va.us

然后使用componentSeparatedByString:@","orsubstringFrom/ToIndex:去掉第一个和最后一个组件中的两个逗号。

这是使用子字符串的解决方案:

NSString* input = @"Christopher Bass,\"Cry, the Beloved Country Final Essay\",cbass@cgs.k12.va.us";
NSArray* split = [input componentsSeparatedByString:@"\""];
NSString* part1 = [split objectAtIndex:0];
NSString* part2 = [split objectAtIndex:1];
NSString* part3 = [split objectAtIndex:2];
part1 = [part1 substringToIndex:[part1 length] - 1];
part3 = [part3 substringFromIndex:1];

NSLog(part1);
NSLog(part2);
NSLog(part3);
于 2012-02-09T09:49:22.640 回答
0

您正在搜索的正则表达式是:\\"(.*)\\"[ ^,]*|([^,]*),

在 ObjC 中:(('\"' && string_1 && '\"' && 0-n spaces) || string_2 except comma) && comma

NSString *str = @"Christopher Bass,\"Cry, the Beloved Country ,Final Essay\",cbass@cgs.k12.va.us,som";
NSString *regEx = @"\\\"(.*)\\\"[ ^,]*|([^,]*),";
NSMutableArray *split = [[str componentsSeparatedByRegex:regEx] mutableCopy];
[split removeObject:@""]; // because it will print always both groups even if the other is empty
NSLog(@"%@", split);

// OUTPUT:
2012-02-07 17:42:18.778 tmpapp[92170:c03] (
    "Christopher Bass",
    "Cry, the Beloved Country ,Final Essay",
    "cbass@cgs.k12.va.us",
    som
)

RegexKitLite 会将两个字符串都添加到数组中,因此您最终会得到数组的空对象。removeObject:@""将删除这些,但如果您需要维护真正的空值(例如,您的源有val,,ue),您必须将代码修改为以下内容:

str = [str stringByReplacingOccurrencesOfRegex:regEx withString:@"$1$2∏"];
NSArray *split = [str componentsSeparatedByString:@"∏"];

$1 和 $2 是上面提到的那两个字符串,∏ 在这种情况下是一个很可能永远不会出现在普通文本中的字符(并且很容易记住:option-shift-p)。

于 2012-02-07T17:11:23.580 回答
0

最后一部分看起来永远不会包含逗号。就我所见,第一个也不会...

像这样拆分字符串怎么样:

NSArray *splitArr = [str componentsSeparatedByString:@","];
NSString *nameStr = [splitArr objectAtIndex:0];
NSString *emailStr = [splitArr lastObject];

NSString *contentStr = @"";
for(int i=1; i<[splitArr count]-1; ++i) {
    contentStr = [contentStr stringByAppendingString:[splitArr objectAtIndex:i]];
}

这将按原样使用第一个和最后一个字符串,并将其余部分组合到内容中。

有点骇人听闻,但名称和电子邮件地址永远不会包含逗号,对吗?

于 2012-02-09T13:56:57.763 回答