引用符で囲まれたテキストを除いて、角かっこ内のスペースを削除します

Aug 19 2020

一致する角かっこ、つまり(との間のスペースを削除できる正規表現を探しています)ただし、角かっこ内の引用符('または")の内側にスペースがある場合を除きます。

現在\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+(?=[^("]*[\)"])、それはまだ間にスペースを見つけ""

誰かが私を正しい方向に向けることができますか?

回答

1 AbdessabourMtk Aug 19 2020 at 19:06

使用した正規表現にいくつか変更を加えました:

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

正規表現は2つの部分に分割され、正規表現はそれらのいずれかに一致します。

  1. 最初の部分は、引用符()が前になく、閉じ括弧が後に続く場合に限り(?<!['"][^,]*)\s+(?=[^(]*\))、可能な限り多くの空白に一致します。\s+'"(?<!['"][^,]*)(?=[^(]*\))
  2. 2番目の部分は、引用符で囲まれず、閉じ括弧が後に続く場合にのみ、\s+(?![^,]*['"])(?=[^(]*\))可能な限り多くの空白に一致します。\s+(?![^,]*['"])(?=[^(]*\))

ここでテストできます

2 DmitryBychenko Aug 19 2020 at 02:27

さて、あなたは2種類の見積もりを持っているので、見積もりの​​見積もりを処理する必要が"あり'ます:

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