Как я могу сопоставить то, что находится между . и {, и объединить их в одну строку, не касаясь интервала между ними.
Это регулярное выражение (\.|@)[^}]*\{ включает окончание { независимо от того, что я пытаюсь сделать, и мне нужна часть (\.|@), чтобы я мог добавить туда больше селекторов. Регулярное выражение онлайн
Да, я знаю, что не должен делать этого с регулярным выражением, но на данный момент у меня нет другого выбора. Поэтому любая помощь будет принята с благодарностью.
Редактировать Я буду использовать это в preg_replace в php
Необработанные данные
.a {
// rules
}
.a-b,
.a-b .b, .a-b.s
.x .y, .x {
// rules
}
@a {
// rules
}
@k {
// rules
}
Выход
.a {
// rules
}
.a-b, .a-b .b, .a-b.s, .x .y, .x {
// rules
}
@a {
// rules
}
@k {
// rules
}
Вот с чем мне нужна помощь... В конце концов, достаточно, если результаты будут такими же, как на выходе.






Обновление: Stupildy, я пропустил, что это был вопрос PHP, а не JS. Мой ответ основан на JS; однако он легко адаптируется к PHP. PHP имеет preg_replace_callback для обратного вызова замены, и шаблон будет таким же.
Если я вас правильно понял, вы хотите свернуть правила CSS с несколькими селекторами и медиа-запросы в одну строку.
Первое, что нужно отметить, это то, что ваш текущий шаблон не безопасен для всех селекторов CSS. Например, он не распространяется на те, которые начинаются с # или *.
Попробуй это:
let edited = str.replace(/^[\*\.#@:\-\[][\s\S]+?(?=\{)/mg, match => {
return match.replace(/\n/g, ' ');
});
Демо .
Объяснение шаблона:
., #, *, @, -, : или [, что соответствует большинству селекторов CSS.}Флаг m (многострочный) указывает JS интерпретировать нашу привязку (^) как относящуюся к любой строке, а не только к первой.
Флаг g (глобальный) обрабатывает все экземпляры, а не только первый найденный.
Это похоже на JavaScript... Я использую PHP.
О боже... вот что я получаю за невнимательность. Что ж, вы можете в основном адаптировать концепции из моего ответа для PHP. У PHP есть preg_replace_callback для запуска замещающего обратного вызова, и шаблон должен работать так же.
Я надеялся, что смогу сделать это одним регулярным выражением. вместо использования обратных вызовов и т. д.
Почему? Инструменты существуют, чтобы позволить вам выполнять задачи. Зачем их игнорировать?
Вы можете использовать
preg_replace('~(?:\G(?!\A)|^[@.])[^{]*?\K\s+~m', ' ', $text)
Посмотрите демонстрацию регулярного выражения . Подробности:
(?:\G(?!\A)|^[@.]) - конец предыдущего успешного совпадения (\G(?!\A)) или (|) начало строки (^), а затем @ или .[^{]*? - любой ноль или более (но как можно меньше) символов, кроме {\K - оператор сброса совпадений, который отбрасывает весь текст, совпавший до сих пор, в общем буфере памяти совпадений.\s+ - любой один или несколько пробельных символов.Обратите внимание на флаг m, который необходим, чтобы ^ соответствовал началу строки, а не только началу всей строки.
Посмотрите демо PHP:
$text = ".a {\r\n // rules\r\n}\r\n\r\n.a-b,\r\n.a-b .b, .a-b.s\r\n.x .y, .x {\r\n // rules\r\n}\r\n\r\n@a {\r\n // rules\r\n}\r\n\r\n@k {\r\n // rules\r\n}";
echo preg_replace('~(?:\G(?!\A)|^[@.])[^{]*?\K\s+~m', ' ', $text);
Вы говорите, что не хотите брать последний
{, но ваш шаблон запрограммирован на его включение.