简体   繁体   English

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

[英]preg_replace replace line breaks across multiple lines between two symbols

How can I match what's between a .我怎样才能匹配. and a { and merge them onto a single line without touching the spacing between them.和一个{并将它们合并到一行而不触及它们之间的间距。

This regex (\.|@)[^}]*\{ inculdes the ending { no matter what I try, and I need the (\.|@) part so I can add more selectors in there.无论我尝试什么,这个正则表达式(\.|@)[^}]*\{都包含结尾{ ,并且我需要(\.|@)部分,以便我可以在其中添加更多选择器。 Online Regex在线正则表达式

Yes, I know I shouldn't be doing this with regex, but I have no other option as of now.是的,我知道我不应该使用正则表达式来执行此操作,但到目前为止我没有其他选择。 So any help will be greatly appreciated.因此,任何帮助将不胜感激。

Edit I'll be using this in preg_replace in php编辑我将在 php 的 preg_replace 中使用它

Raw data原始数据

.a {
    // rules
}

.a-b,
.a-b .b, .a-b.s
.x .y, .x {
    // rules
}

@a {
    // rules
}

@k {
    // rules
}

Output Output

.a {
    // rules
}

.a-b, .a-b .b, .a-b.s, .x .y, .x {
    // rules
}

@a {
    // rules
}

@k {
    // rules
}

You can use您可以使用

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

See the regex demo .请参阅正则表达式演示 Details:细节:

  • (?:\G(?.\A)|^[@.]) - end of the previous successful match ( \G(?!\A) ) or ( | ) start of string ( ^ ) and then @ or . (?:\G(?.\A)|^[@.]) - 上一个成功匹配的结束 ( \G(?!\A) ) 或 ( | ) 字符串开头 ( ^ ) 然后是@.
  • [^{]*? - any zero or more (but as few as possible) chars other than { - 除{之外的任何零个或多个(但尽可能少)字符
  • \K - match reset operator that discards all text matched so far in the overall match memory buffer \K - 匹配重置运算符,丢弃到目前为止在整体匹配 memory 缓冲区中匹配的所有文本
  • \s+ - any one or more whitespace chars. \s+ - 任何一个或多个空格字符。

Note the m flag that is necessary to make ^ match start of a line, not just start of a whole string.请注意使^匹配行的开头所必需的m标志,而不仅仅是整个字符串的开头。

See the PHP demo :请参阅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);

Update: Stupildy, I missed that this was a PHP question, not a JS one.更新:愚蠢,我错过了这是一个 PHP 问题,而不是 JS 问题。 My answer is JS-based;我的答案是基于 JS 的; however it is easily adapted to PHP.但是它很容易适应 PHP。 PHP has preg_replace_callback for the replacement callback, and the pattern will be the same. PHP 有preg_replace_callback用于替换回调,模式将相同。


If I understand you right, you want to collapse multi-selector CSS rules and media queries into single lines.如果我理解正确,您想将多选择器 CSS 规则和媒体查询折叠成单行。

The first thing to point out is that your current pattern isn't safe for all CSS selectors.首先要指出的是,您当前的模式并非对所有 CSS 选择器都是安全的。 It won't cover those that start with # or * , for example.例如,它不会涵盖以#*开头的那些。

Try this:尝试这个:

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

Demo .演示

Pattern explanation:图案说明:

  • Anchor to the start of a line锚定到行首
  • The line must start with .该行必须以. , # , * , @ , - , : or [ , covering most CSS selectors. , # , * , @ , - , :[ ,涵盖大多数 CSS 选择器。
  • Following the selector(s), match whatever comes after, until...在选择器之后,匹配后面的任何内容,直到...
  • }
  • We run each match through a callback, replacing line breaks with spaces.我们通过回调运行每场比赛,用空格替换换行符。

The m (multi-line) flag tells JS to interpret our anchor ( ^ ) as pertaining to any line, not just the first. m (多行)标志告诉 JS 将我们的锚( ^ )解释为与任何行有关,而不仅仅是第一行。

The g (global) flag handles all instances, not just the first found. g (全局)标志处理所有实例,而不仅仅是第一个找到的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM