Удалите пробелы в скобках, кроме текста в кавычках
Я ищу регулярное выражение, которое может удалять пробелы, когда они находятся между соответствующими скобками, то есть (
и )
, за исключением случаев , когда внутри скобок есть пробелы внутри кавычек ( '
или "
) .
В настоящее время у меня есть регулярное выражение \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'
, без\
escape-символа.'
В"
"
тексте может быть :text="text with ' inside"
, без\
escape-символа.- Перед кавычками в строке нет escape-символа:
text='This is \" not there'
Я знаю, что есть довольно много вопросов о шаблонах регулярных выражений, но я не смог найти ни одного, который помог бы. Среди многих вещей, которые я пробовал, были поиски только промежуточных значений (
до '
или "
с \s+(?=[^("]*[\)"])
, но это все еще находит пробелы между "
и "
.
Может ли кто-нибудь указать мне в правильном направлении?
Ответы
Я внес некоторые изменения в регулярное выражение, которое вы использовали:
# match a space or more
# if the fol
(?<!['"][^,]*)\s+(?=[^(]*\))|\s+(?![^,]*['"])(?=[^(]*\))
регулярное выражение разделено на две части, регулярное выражение будет соответствовать любой из них:
- первая часть
(?<!['"][^,]*)\s+(?=[^(]*\))
соответствует как можно большему количеству пробелов,\s+
которым не предшествует кавычка'"
((?<!['"][^,]*)
), и если только за ней следует закрывающая скобка.(?=[^(]*\))
- вторая часть
\s+(?![^,]*['"])(?=[^(]*\))
соответствует как можно большему количеству пробелов , за\s+
которыми не следует кавычка,(?![^,]*['"])
и только если за ней следует закрывающая скобка(?=[^(]*\))
.
вы можете протестировать это здесь
Ну, так как у вас есть два вида цитат, "
и '
вам приходится иметь дело с цитатой цитаты :
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")