Supprimer les espaces entre crochets, à l'exception du texte entre guillemets
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
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:
- 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.(?=[^(]*\))
- 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
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")