2013-10-21 189 views
2

我有了行类似这样的CSV文件不同的是:正则表达式删除各地逗号,空格时引述

1, 4,  2, "PUBLIC, JOHN Q" ,ACTIVE , 1332 

我要寻找一个正则表达式替换将匹配对这些行吐出类似的东西这样的:

1,4,2,"PUBLIC, JOHN Q",ACTIVE,1332 

我想这将是相当容易:我做了表达([ \t]+,),取而代之。我用,替代(,[ \t]+)作为补充表达式,我认为我已经实现了修剪和左修剪字符串的好方法。

...但后来我发现我的"PUBLIC, JOHN Q"现在是"PUBLIC,JOHN Q"这不是我想要的。 (注意逗号后面的空格现在已经消失)。

什么是适当的表达式来修剪逗号前后的空格,但保留引用的文本不变?

UPDATE

为了澄清,我正在使用的应用程序来处理文件。这个应用程序允许我定义多个正则表达式替换;它不提供解析功能。虽然这可能不是这个理想的机制,但它肯定会为这个文件创建另一个应用程序。

+6

你为什么不分析? –

+6

使用CSV解析器 - 不要尝试重新发明轮子!查看[Microsoft.VisualBasic.FileIO.TextFieldParser](http://msdn.microsoft.com/zh-cn/library/microsoft.visualbasic.fileio.textfieldparser.aspx)。 – Tim

+0

我会解析文件并将其重新构建在一起。无需RegEx,我不好笑。 –

回答

2

如果您的工具使用的发动机是C#正则表达式引擎,那么你可以尝试下面的表达式:

(?<!,\s*"(?:[^\\"]|\\")*)\s+(?!(?:[^\\"]|\\")*"\s*,) 

更换空字符串。

这些家伙的答案假设报价是平衡的,并用于计算确定空间是否是报价值的一部分。

我的表达式查找所有不属于引用值的空格。

RegexHero Demo

+0

嗨@Sniffer什么(?<!,是什么意思?(我对正则表达式比较陌生,不知道<和!在组中的含义(?代表非捕获组对)? – lucacerone

+0

@lucacerone它是自从我使用正则表达式以来,我已经有一段时间了,因此您需要检查C#文档以确保它正确,但是我记得这是一个负面的后顾之忧。 –

0
 string format(string val) 
     { 
      if (val.StartsWith("\"")) val = " " + val; 
      string[] vals = val.Split('\"'); 
      for (int i = 0; i < vals.Length; i += 2) vals[i] = vals[i].Replace(" ", "").Replace("\t", ""); 
      return string.Join("\t", vals); 
     } 

如果你有正确关闭在

1

之间有一些CSV去图书馆或分析文件自己会更容易,IMO应该在这里最好选择带引号的字符串这将工作。

但如果你真的坚持一个正则表达式,你可以用这一个:

"\s+(?=([^\"]*\"[^\"]*\")*[^\"]*$)" 

并与空字符串代替它 - ""

此正则表达式的一个或多个空格匹配,其次是偶报价数量。只有当你有平衡的报价时,这当然会起作用。

(?x)  # Ignore Whitespace 
\s+  # One or more whitespace characters  
(?=  # Followed by 
    (   # A group - This group captures even number of quotes 
    [^\"]*  # Zero or more non-quote characters 
    \"   # A quote 
    [^\"]*  # Zero or more non-quote characters 
    \"   # A quote 
    )*   # Zero or more repetition of previous group 
    [^\"]*  # Zero or more non-quote characters 
    $   # Till the end 
)   # Look-ahead end 
1

像这样的事情会做的工作:

(?<!(^[^"]*"[^"]*(("[^"]*){2})*))[\t ]*,[ \t]* 

它匹配[\t ]*,[ \t]*,只有当不被奇数引号的前面。

0

忘记正则表达式(参见问题Bart的评论,正则表达式是不适合CSV)。

public static string ReduceSpaces(string input) 
{ 
    char[] a = input.ToCharArray(); 
    int placeComma = 0, placeOther = 0; 
    bool inQuotes = false; 
    bool followedComma = true; 
    foreach(char c in a) { 
     inQuotes ^= (c == '\"'); 
     if (c == ' ') { 
      if (!followedComma) 
       a[placeOther++] = c; 
     } 
     else if (c == ',') { 
      a[placeComma++] = c; 
      placeOther = placeComma; 
      followedComma = true; 
     } 
     else { 
      a[placeOther++] = c; 
      placeComma = placeOther; 
      followedComma = false; 
     } 
    } 
    return new String(a, 0, placeComma); 
} 

演示:http://ideone.com/NEKm09

相关问题