删除括号内的空格(引号中的文本除外)

时间:2020-08-18 18:06:24

标签: c# .net 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 with " inside',而没有\转义字符。
  • ' "文本中可以有"text="text with ' inside",而没有\转义字符。
  • text='This is \" not there'
  • 中的引号前没有转义字符。

我知道关于正则表达式模式有很多问题,但是我找不到能解决问题的方法。我尝试过的许多方法中,都期望仅在('"\s+(?=[^("]*[\)"])之间找到东西,但是仍然找到之间的空间""

有人可以指出我正确的方向吗?

2 个答案:

答案 0 :(得分:2)

好吧,由于您有两种{em} "'这两种报价,所以您必须处理 quote报价

  abc"def pqr' ijk" "klm ' xyz"

请注意,两个引号均带有撇号,这就是为什么不起作用的原因。与括号相同。我怀疑一个 简单的正则表达式可以为您提供帮助,但有限状态机可以:

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();
}

演示:

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")

答案 1 :(得分:1)

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

# match a space or more 
# if the fol
(?<!['"][^,]*)\s+(?=[^(]*\))|\s+(?![^,]*['"])(?=[^(]*\))

正则表达式分为两部分,正则表达式将与它们之一匹配:

  1. 第一部分(?<!['"][^,]*)\s+(?=[^(]*\))与尽可能多的空白\s+相匹配,并且前面没有引号'"(?<!['"][^,]*)),并且仅在后面加上右括号。 (?=[^(]*\))
  2. 第二部分\s+(?![^,]*['"])(?=[^(]*\))匹配尽可能多的空格\s+,只有在其后接右括号(?![^,]*['"])后,该空格才不能由引号(?=[^(]*\))引起。 / li>

you can test it here