我有一个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"
,这不是我想要的。 (注意逗号后面的空格现在已经消失了。)
在逗号之前和之后修剪空格的适当表达式是什么,但保留引用文本不变?
更新
为了澄清,我正在使用一个应用程序来处理该文件。这个应用程序允许我定义多个正则表达式替换;它不提供解析功能。虽然这可能不是理想的机制,但它肯定会为这个文件制作另一个应用程序。
答案 0 :(得分:2)
如果您的工具使用的引擎是C#正则表达式引擎,那么您可以尝试以下表达式:
(?<!,\s*"(?:[^\\"]|\\")*)\s+(?!(?:[^\\"]|\\")*"\s*,)
替换为空字符串。
这些家伙的答案假设报价是平衡的,并使用计数来确定空间是否是引用值的一部分。
我的表达式查找不属于引用值的所有空格。
答案 1 :(得分: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
答案 2 :(得分:1)
这样的事情可能会起到作用:
(?<!(^[^"]*"[^"]*(("[^"]*){2})*))[\t ]*,[ \t]*
哪个匹配[\t ]*,[ \t]*
,只有在没有前面有奇数引号的情况下才会匹配。
答案 3 :(得分: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);
}
如果您在
之间正确关闭了引用的字符串,这将有效答案 4 :(得分: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);
}