正则表达式匹配括号之间的换行符和制表符

regex to match line breaks and tabs between brackets

我正在尝试从如下数据的括号内的内容中删除换行符和制表符:

settings:a [
    a:[
        a:a
        b:b
    ]
    b:[
        a:a
        b:b
    ]
]

settings:b [
    a:[
        a:a
        b:b
    ]
]

所以变成:

settings:a [ a:[ a:a b:b ] b:[ a:a b:b ] ] 
settings:b [ a:[ a:a b:b ] ]

我正在使用的正则表达式 \n(?=[^\[\]]*\]) 在某种程度上有效,但我没有得到如上所示的输出。你能帮忙吗?

Regex Example

您可以在 preg_replace_callback:

中使用这个递归正则表达式
$s = 'settings:a [
    a:[
        a:a
        b:b
    ]
    b:[
        a:a
        b:b
    ]
]';

echo preg_replace_callback('/\[(?:([^][]*)|(?R))*\]/', function ($m) {
      return preg_replace('/\s+/', ' ', $m[0]); }, $s) . "\n";

输出:

settings:a [ a:[ a:a b:b ] b:[ a:a b:b ] ]

RegEx Demo

您可以将以下正则表达式与 preg_replace 一起使用(因此,一次正则表达式传递即可):

[\t\n]+(?=[^][]*(?:(\[(?:[^][]++|(?1))*])[^][]*)*])

参见regex demo。详情:

  • [\t\n]+ - 一个或多个制表符或换行符(如果需要匹配 any 空格,请使用 \s,并添加 u修饰符标志,如果你需要处理Unicode文本)
  • (?=[^][]*(?:(\[(?:[^][]++|(?1))*])[^][]*)*]) - 正向前瞻,要求其模式立即匹配到当前位置的右侧:
    • [^][]* - []
    • 以外的零个或多个字符
    • (?:(\[(?:[^][]++|(?1))*])[^][]*)* - 零次或多次出现
      • (\[(?:[^][]++|(?1))*]) - 第 1 组(技术上的,递归工作所必需的):一个 [,然后是成对嵌套 [] 之间的任何子字符串,然后是一个]
      • [^][]* - []
      • 以外的零个或多个字符
    • ] - 一个 ] 字符。

参见PHP demo:

$re = '/[\t\n]+(?=[^][]*(?:(\[(?:[^][]++|(?1))*])[^][]*)*])/';
$str = "settings:a [\n  a:[\n       a:a\n       b:b\n   ]\n b:[\n       a:a\n       b:b\n   ]\n]\n\nsettings:b [\n  a:[\n   \n\na:a\n       b:b\n   ]\n]";
echo preg_replace($re, ' ', $str);
// => settings:a [ a:[ a:a b:b ] b:[ a:a b:b ] ]
//    settings:b [ a:[ a:a b:b ] ]