C# 删除括号内的空格,引号中的文本除外

C# 删除括号内的空格,引号中的文本除外,c#,.net,regex,C#,.net,Regex,我正在寻找一个正则表达式,它可以删除匹配括号之间的空格,即和,除非引号内或括号内有空格 我目前有一个regex\s+?=[^]*\,它删除了括号中的所有空格。当引号中有空格时也是如此 // My input do something with(in = 1, text='some text with spaces' , text2="also has spaces") // My current output do something with(in=1,text='som

我正在寻找一个正则表达式,它可以删除匹配括号之间的空格,即和,除非引号内或括号内有空格

我目前有一个regex\s+?=[^]*\,它删除了括号中的所有空格。当引号中有空格时也是如此

// My input
do something with(in = 1, text='some text with spaces' , text2="also has spaces")

// My current output
do something with(in=1,text='sometextwithspaces',text2="alsohasspaces")

// My desired output
do something with(in=1,text='some text with spaces',text2="also has spaces")
此外:

引号只能在括号内找到 “”text:text='text with inside'中可以有不带\escape字符的字符。 可以有“in-text:text=text with”在内,不带\转义字符。 字符串中引号前没有转义字符:text='This is\not There' 我知道关于正则表达式模式有很多问题,但我找不到一个解决这个问题的方法。在我尝试过的许多方法中,look Forward只能在“直到”或使用\s+?=[^]*[\]之间找到东西,但仍然可以在和之间找到空格

有人能给我指出正确的方向吗?

好吧,既然你有两种报价,而且“你必须处理报价中的报价:

请注意,两个撇号都被引用,这就是为什么不起作用。括号也一样。我怀疑是否有人 简单的正则表达式可以帮助解决此问题,但有限状态机可以:

private static string RemoveSpaces(string value) {
  if (string.IsNullOrEmpty(value))
    return value;

  bool inQuotation = false;
  bool inApostroph = false;
  int bracketCount = 0;
  int escapeCount = 0;
  StringBuilder result = new StringBuilder(value.Length);

  foreach (char c in value) {
    if (inQuotation) {
      result.Append(c);
      inQuotation = c != '"' || (escapeCount % 2 != 0);
    }
    else if (inApostroph) {
      result.Append(c);
      inApostroph = c != '\'' || (escapeCount % 2 != 0);
    }
    else {
      if (c != ' ' || bracketCount <= 0)
        result.Append(c);

      if (c == '(')
        bracketCount += 1;
      else if (bracketCount == ')')
        bracketCount -= 1;

      inQuotation = c == '"' && (escapeCount % 2 == 0);
      inApostroph = c == '\'' && (escapeCount % 2 == 0);
    }

    escapeCount = c == '\\' ? escapeCount + 1 : 0;
  }
  return result.ToString();
}
结果:

那么既然你有两种报价,"你要处理报价中的报价:

请注意,两个撇号都被引用,这就是为什么不起作用。括号也一样。我怀疑是否有人 简单的正则表达式可以帮助解决此问题,但有限状态机可以:

private static string RemoveSpaces(string value) {
  if (string.IsNullOrEmpty(value))
    return value;

  bool inQuotation = false;
  bool inApostroph = false;
  int bracketCount = 0;
  int escapeCount = 0;
  StringBuilder result = new StringBuilder(value.Length);

  foreach (char c in value) {
    if (inQuotation) {
      result.Append(c);
      inQuotation = c != '"' || (escapeCount % 2 != 0);
    }
    else if (inApostroph) {
      result.Append(c);
      inApostroph = c != '\'' || (escapeCount % 2 != 0);
    }
    else {
      if (c != ' ' || bracketCount <= 0)
        result.Append(c);

      if (c == '(')
        bracketCount += 1;
      else if (bracketCount == ')')
        bracketCount -= 1;

      inQuotation = c == '"' && (escapeCount % 2 == 0);
      inApostroph = c == '\'' && (escapeCount % 2 == 0);
    }

    escapeCount = c == '\\' ? escapeCount + 1 : 0;
  }
  return result.ToString();
}
结果:


我对您使用的正则表达式进行了一些修改:

匹配一个或多个空格 如果 ? 尽可能多地匹配前面没有引号“??=[^]的空白\s+*\ 第二部分\s+?![^,]*[']?=[^]*\匹配尽可能多的空格\s+后面没有引号?![^,]*[']并且仅当它后面跟一个右括号时?=[^]*\。
我对您使用的正则表达式进行了一些修改:

匹配一个或多个空格 如果 ? 尽可能多地匹配前面没有引号“??=[^]的空白\s+*\ 第二部分\s+?![^,]*[']?=[^]*\匹配尽可能多的空格\s+后面没有引号?![^,]*[']并且仅当它后面跟一个右括号时?=[^]*\。
我使用C中的模式。您是否在文本中使用了text='some put\和\'to***以及我的代码'?对于嵌套构造/计数、编写简单解析器来说,正则表达式是非常糟糕的选择instead@AlexeiLevenkov否,请参阅更新的问题。您有权访问代码吗?你现在使用的是什么代码?@WiktorStribiżew是的,我有权访问该代码。我目前使用的是我问题中的第一个正则表达式。我使用的是C中的模式。您是否有text='some put\的大小写,并带有\'to***with my code'?对于嵌套构造/计数、编写简单解析器来说,正则表达式是非常糟糕的选择instead@AlexeiLevenkov否,请参阅更新的问题。您有权访问代码吗?你现在使用的是什么代码?@WiktorStribiżew是的,我有权访问该代码。我正在使用我问题中的第一个正则表达式。谢谢你的回答!我刚刚了解了regex,发现它的功能非常惊人。在我的热情中,我可能过度使用了它。所以,今天我了解到它的功能也有局限性。@Roald:解析和解析某种源代码并不是正则表达式的强项;请注意,如果您想添加更多状态,例如引入注释/*…*/你可以很容易地做到这一点的情况下,FSMThanks的答案!我刚刚了解了regex,发现它的功能非常惊人。在我的热情中,我可能过度使用了它。所以,今天我了解到它的功能也有局限性。@Roald:解析和解析某种源代码并不是正则表达式的强项;请注意,如果您想添加更多状态,例如引入注释/*…*/在使用FSMThanks的情况下,您可以轻松地执行此操作。您的解决方案已加入到具有属性的项目中!反例:反例123 456 789;预期:括号内的空格匹配,实际:它们不匹配,谢谢。您的解决方案已加入到具有属性的项目中!反例:反例123 456 789;预期:括号内的空格匹配,实际:不匹配
string test =
  @"do something with(in = 1, text='some text with spaces' , text2=""also has spaces"")";

Console.WriteLine(RemoveSpaces(test));
do something with(in=1,text='some text with spaces',text2="also has spaces")