preg_replace 替换两个符号之间多行的换行符

preg_replace replace line breaks across multiple lines between two symbols

如何匹配 .{ 之间的内容,并将它们合并成一行而不影响它们之间的间距。

这个正则表达式 (\.|@)[^}]*\{ 包含结尾 { 无论我尝试什么,我都需要 (\.|@) 部分以便我可以在其中添加更多选择器。 Online Regex

是的,我知道我不应该用正则表达式来做这件事,但我现在别无选择。因此,我们将不胜感激任何帮助。

编辑 我将在 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
}

更新: 愚蠢,我错过了这是一个 PHP 问题,而不是 JS 问题。我的答案是基于 JS 的;然而它很容易适应 PHP。 PHP 有 preg_replace_callback 用于替换回调,模式将相同。


如果我没理解错的话,您想将多选择器 CSS 规则和媒体查询折叠成单行。

首先要指出的是,您当前的模式对所有 CSS 选择器都不安全。例如,它不会涵盖以 #* 开头的内容。

试试这个:

let edited = str.replace(/^[\*\.#@:\-\[][\s\S]+?(?=\{)/mg, match => {
    return match.replace(/\n/g, ' ');
});

Demo.

图案说明:

  • 行首的锚点
  • 该行必须以 .#*@-: 或 [=20= 开头],涵盖大多数 CSS 选择器。
  • 选择器之后,匹配后面的任何内容,直到...
  • }
  • 我们运行通过回调进行每次匹配,用空格替换换行符。

m(多行)标志告诉 JS 将我们的锚点 (^) 解释为与任何行有关,而不仅仅是第一行。

g(全局)标志处理所有实例,而不仅仅是第一个找到的实例。

你可以使用

preg_replace('~(?:\G(?!\A)|^[@.])[^{]*?\K\s+~m', ' ', $text)

regex demo。详情:

  • (?:\G(?!\A)|^[@.]) - 上一个成功匹配的结尾 (\G(?!\A)) 或 (|) 字符串的开头 (^) 然后是 @.
  • [^{]*? - {
  • 以外的任何零个或多个(但尽可能少)字符
  • \K - 匹配重置运算符,丢弃整个匹配内存缓冲区中到目前为止匹配的所有文本
  • \s+ - 任何一个或多个空白字符。

请注意 m 标志,这是使 ^ 匹配行的开头所必需的,而不仅仅是整个字符串的开头。

参见 PHP demo:

$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);