Tırnak işaretlerindeki metinler dışında parantez içindeki boşlukları kaldırın

Aug 19 2020

Onların eşleşen parantez, ie arasında olduğunda boşlukları kaldırın bir regex arıyorum (ve ), dışında tırnak işareti (iç boşluklar varken 'ya ") parantez.

Şu anda \s+(?=[^(]*\))parantezler arasında bulunan tüm boşlukları kaldıran normal ifadeye sahibim . Tırnak içinde boşluk olduğunda da.

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

Ayrıca:

  • Tırnak işaretleri yalnızca parantez içinde bulunabilir
  • Olabilir "de ' 'metnin: text='text with " inside'olmadan \kaçış karakteri.
  • Olabilir 'de " "metnin: text="text with ' inside"olmadan \kaçış karakteri.
  • Orada hiçbir dizede tırnak işareti önce kaçış karakteri:text='This is \" not there'

Normal ifade kalıpları hakkında pek çok soru olduğunu biliyorum, ancak hile yapan birini bulamadım. Ben denedim çok şey arasında ileri sadece aradaki şeyler bulmak görünüm vardı (dek 'ya "sahip \s+(?=[^("]*[\)"]), ancak yine de aradaki boşlukları bulur "ve ".

Birisi beni doğru yönü gösterebilir mi?

Yanıtlar

1 AbdessabourMtk Aug 19 2020 at 19:06

Kullandığınız normal ifadede bazı değişiklikler yaptım:

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

normal ifade iki kısma ayrılır, normal ifade bunlardan biriyle eşleşir:

  1. ilk bölüm (?<!['"][^,]*)\s+(?=[^(]*\))mümkün olduğu kadar çok beyaz boşlukla eşleşir, \s+bu boşluktan önce bir tırnak '"( (?<!['"][^,]*)) gelmez ve sadece onu bir kapanış parantezi takip ederse.(?=[^(]*\))
  2. ikinci bölüm \s+(?![^,]*['"])(?=[^(]*\)), mümkün olduğunca çok beyaz boşlukla eşleşir, \s+bunun yerine bir alıntı gelmez (?![^,]*['"])ve yalnızca onu bir kapanış parantezi takip ederse (?=[^(]*\)).

burada deneyebilirsin

2 DmitryBychenko Aug 19 2020 at 02:27

Eh, sen beri iki alıntıların tür "ve 'sen uğraşmak zorunda teklifin tırnak :

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

O Not Her iki kesme işareti enquoted ve işi yok bu yüzden. Parantez ile aynı . Basit bir düzenli ifadenin burada yardımcı olabileceğinden şüpheliyim, ancak Sonlu Durum Makinesi şunları yapabilir:

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

Demo:

string test =
  @"do something with(in = 1, text='some text with spaces' , text2=""also has spaces"")";

Console.WriteLine(RemoveSpaces(test));

Sonuç:

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