匹配任何换行符,除了分隔符之间的换行符

时间:2016-07-11 14:04:15

标签: c# regex

我已经提供了以下CSV文件:

"A";"B
C";"D"
"E";"F"
"G
H"

我需要删除放在文本中的换行符,除了直接放在两个分隔符之间的换行符(在这种情况下是双引号"")。仅表示换行符,即两个双引号("\n")之间的唯一符号应该出现在文件中。

这个想法是有一个正则表达式,即:

查找所有新行字符,但双引号之间的字符除外(行末尾的字符除外,因为每行始终以双引号开头并完成)并将其替换为空间。

因此处理上述文件的结果应为:

"A";"B C";"D"
"E";"F"
"G H"

换句话说,正则表达式在分隔符之间找到新行字符应该:

查找除\n

以外的所有"\n"

我尝试了以下正则表达式:[^"\n"][\n]以匹配除\n之外的每个"\n",但是在Sublime Text 2中对此进行测试时,它会选择所需的新行字符,但也会选择之前的单个字符它:

enter image description here

这意味着当我用空格替换找到的地点时,它也会替换BG字符,这是不期望的。

我还想提一下,我将使用该Regex在C#代码中执行替换操作。

你知道如何按需要工作吗?

编辑2016-07-14

我尝试了下面提出的 OmegaMan 。 它适用于我上面指定的情况,但我没有发现它可能会遇到文件中的多行。例如:

给定CSV文件(引用" pathToTheExampleFile"稍后用C#代码):

"A";"B
C";"D"
"E";"F";"Part1
Part2
Part3
";

在代码中使用 OmegaMan 的解决方案,我得到了这样的结果:

"A";"B C";"D"
"E";"F";"Part1 Part2
Part3
";

预计会:

"A";"B C";"D"
"E";"F";"Part1 Part2 Part3  ";

然而,在执行 OmegaMan 的替换操作三次后,就像这样:

string data = File.ReadAllText(@"pathToTheExampleFile");

string pattern = @"(?<=\x22[^\x22\r\n]+)([\r\n]+)";

var result = Regex.Replace(data, pattern, " ");

result = Regex.Replace(result, pattern, " ");

result = Regex.Replace(result, pattern, " ");

Console.WriteLine(result);

我得到了我想要的结果。所以它需要多线匹配。 我没有看到正则表达式可能不起作用的任何其他情况。

如果您有任何想法如何修改正则表达式,将不胜感激。

编辑2016-07-15:

我必须补充一点,它可以添加这个丑陋的解决方案:

while (Regex.IsMatch(data, pattern))
{
    data = Regex.Replace(data, pattern, " ");
}

最后,data包含预期的字符串。它非常难看,但我确信它在某种程度上可以用正则表达式来实现。

4 个答案:

答案 0 :(得分:1)

您可以使用基于前瞻性的正则表达式进行搜索:

\n(?!")

并将其替换为:

" "

\n(?!")将匹配任何未跟随双引号的\n

RegEx Demo

答案 1 :(得分:1)

通过使用非消费性外观来验证是否存在打开的引用文本,这将完成工作并用空格替换以下\r\n

string data = "\"A\";\"B\r\nC\";\"D\"\r\n\"E\";\"F\"\r\n\"G\r\nH\"";

string pattern = @"(?<=\x22[^\x22\r\n]+)([\r\n]+)";

Regex.Replace(data, pattern, " " )

请注意,\x22"的转义。

替换返回此:

"A";"B C";"D"
"E";"F"
"G H"

答案 2 :(得分:0)

我建议很容易实现循环而不是复杂的正则表达式:

private static String trimNewLines(String value) {
  if (null == value)
    return value;

  StringBuilder sb = new StringBuilder(value.Length);

  Boolean inQuotation = false;

  foreach (char ch in value) {
    if (ch == '"')
      inQuotation = !inQuotation;

    if (inQuotation || ch != '\r' || ch != '\n')
      sb.Append(ch);
  }

  return sb.ToString();
}

...

String result = trimNewLines(File.ReadAllText(@"c:\MyData.csv"));

答案 3 :(得分:0)

尝试

string pattern = @"([^\x22])(\r\n)+|(;\x22)\r\n";
string result = Regex.Replace(data, pattern, "$1$3 ");

我得到了

"A";"B C";"D"
"E";"F";"Part1 Part2 Part3 "
"G G2 G3";"H";" I I2 I3 "

Fot这个输入:

"A";"B
C";"D"
"E";"F";"Part1
Part2
Part3
"
"G
G2
G3";"H";"
I

I2

I3
"

请参阅https://dotnetfiddle.net/uc538C