Supprimer les espaces entre crochets, à l'exception du texte entre guillemets

Aug 19 2020

Je recherche une expression régulière qui peut supprimer les espaces lorsqu'ils sont entre crochets correspondants, c'est (-à- dire et ), sauf lorsqu'il y a des espaces entre guillemets ( 'ou ") à l' intérieur des crochets.

J'ai actuellement le regex \s+(?=[^(]*\)), qui supprime tous les espaces trouvés entre crochets. Donc aussi quand il y a des espaces entre guillemets.

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

En outre:

  • Les guillemets ne peuvent être trouvés qu'à l'intérieur des crochets
  • Il peut y avoir "dans le ' 'texte:, text='text with " inside'sans le \caractère d'échappement.
  • Il peut y avoir 'dans le " "texte:, text="text with ' inside"sans le \caractère d'échappement.
  • Il n'y a pas de caractère d'échappement avant le guillemet dans la chaîne:text='This is \" not there'

Je sais qu'il y a pas mal de questions sur les modèles d'expression régulière, mais je n'ai pas pu en trouver un qui fasse l'affaire. Parmi les nombreuses choses que j'ai essayées, il y avait chercher en avant pour ne trouver que des choses entre (jusqu'à 'ou "avec \s+(?=[^("]*[\)"]), mais cela trouve toujours les espaces entre "et ".

Quelqu'un peut me diriger dans la bonne direction?

Réponses

1 AbdessabourMtk Aug 19 2020 at 19:06

J'ai apporté quelques modifications à l'expression régulière que vous avez utilisée:

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

l'expression régulière est divisée en deux parties, l'expression régulière correspondra à l'une d'entre elles:

  1. la première partie (?<!['"][^,]*)\s+(?=[^(]*\))correspond à autant d'espace blanc que possible \s+qui n'est pas précédé d'un guillemet '"( (?<!['"][^,]*)) et si seulement il est suivi d'une parenthèse fermante.(?=[^(]*\))
  2. la deuxième partie \s+(?![^,]*['"])(?=[^(]*\))correspond à autant d'espaces blancs que possible \s+qui ne sont pas (?![^,]*['"])suivis d'un guillemet et seulement s'ils sont suivis d'une parenthèse fermante (?=[^(]*\)).

vous pouvez le tester ici

2 DmitryBychenko Aug 19 2020 at 02:27

Eh bien, puisque vous avez deux types de devis, "et que 'vous devez vous occuper de devis de devis :

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

Notez que les deux apostrophes sont mises en file d'attente et c'est pourquoi ne fonctionnent pas. Idem avec les crochets . Je doute qu'une simple expression régulière puisse aider ici, mais Finite State Machine peut:

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

Démo:

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

Console.WriteLine(RemoveSpaces(test));

Résultat:

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