此时我无法控制生成此文件的源系统。
我有一个使用双引号作为文本限定符的csv文件。在合格的文本字段中,我有时会有双引号,表示英寸等。如下所示:
something not qualified,"12" x 12" something qualified, becuase it has a comma",this one is not qualified and needs no fixing a 12" x 12"
这些应该使用以下两组引号进行转义:
something not qualified,"12"" x 12"" something qualified, becuase it has a comma",this one is not qualified and needs no fixing a 12" x 12"
我正在尝试使用c#和regex编写一些清理代码。我可以编写代码来选择,"
和",
之间的所有内容,但我无法弄清楚如何在这些分隔符中获取双引号。
我可以拥有没有限定符(没有逗号)的字段,这些字段可以有一个双引号而且不需要修复。
以下是regexr https://regexr.com/3pq51
中的内容((?<=,").*(?=",))
答案 0 :(得分:1)
这是一个非常令人讨厌的问题,我实际上并不确定它很容易解决(甚至可能在100%的时间内解决),并且与魔法接壤。
唯一的好处是它只适用于英寸(所以你声明),你知道有多少个字段。
然而,似乎有太多Degrees of Freedom并且总会给出误报。即你所拥有的只是一个格式错误的 CSV ,存在以下基本问题: -
也许某人有一种启发式方法,但我猜测任何可靠的解决方案都需要返回“我不确定”#34;导致某些情况...
总之,正则表达式无法为您解决此问题。
无论如何,祝你好运,也许最好从另一端攻击这个。
答案 1 :(得分:1)
您输入的字符串很乱,而且可能无法提出防水解决方案。你可以尝试的一件事是捕捉," ... ",
之间的所有内容:
[^,]+|,"(.*?)",
如果您的限定字符串中有另一个",
,这显然会中断。
示例代码:
using System;
using System.Text.RegularExpressions;
public class Program
{
public static void Main()
{
string pattern = @"[^,]+|,""(.*?)"",";
string input = @"something not qualified,""12"" x 12"" something qualified, becuase it has a comma"",this one is not qualified and needs no fixing a 12"" x 12""";
RegexOptions options = RegexOptions.Multiline;
foreach (Match m in Regex.Matches(input, pattern, options))
{
if(m.Groups[1].Success)
Console.WriteLine("'{0}'", m.Groups[1].Value);
else
Console.WriteLine("'{0}'", m.Value);
}
}
}
输出:
something not qualified
12" x 12" something qualified, becuase it has a comma
this one is not qualified and needs no fixing a 12" x 12"
答案 2 :(得分:1)
如果分隔字符串,"
和",
永远不会在带引号的字符串中发生,您可以使用无限的lookbehind或\G
来查找此边界。由于\G
- 方法更适合并且更快找到匹配或失败,我会继续使用它:
((?:\A|,)"|\G(?!\A))([^"]*)(")(?!,|\Z)
C#代码(参见现场演示here):
str = Regex.Replace(str, @"((?:\A|,)""|\G(?!\A))([^""]*)("")(?!,|\Z)", @"$1$2$3$3");
正则表达式细分:
(
开始捕获第一组
(?:\A|,)"
匹配"
|
或\G(?!\A)
匹配上一场比赛结束的地方)
结束捕获第一组([^"]*)
捕捉除"
(")
抓取"
(?!,|\Z)
不应该使用逗号或输入字符串结尾答案 3 :(得分:1)
谢谢大家的帮助。它帮助我看到我需要采取分阶段的方法。
首先,我得到了所有内容,“和”,。然后我找到了它们出现的模式中有单引号的模式,并用2个双引号和空格替换。为了以防万一,我每次都这样做。
string matchPattern = "((?<=,\").*?(?=\",))";
string input = "something not qualified,\"12\" x 12\" something qualified, becuase it has a comma\",this one is not qualified and needs no fixing a 12\" x 12\",\"8\" X 8\" sign, plain\",one more";
var newLine = input;
Regex regx = new Regex(matchPattern);
Regex regxReplace = new Regex(@"(?<=\w)""[^\w|\""]");
var matches = regx.Matches(input);
foreach (Match matchingString in matches)
{
var value = matchingString.Value;
if (regxReplace.IsMatch(value))
{
changed = true;
var newReplacementString = regxReplace.Replace(value, "\"\" ");
newLine = newLine.Replace(matchingString.Value, newReplacementString);
}
}
return newLine;