如果不包含“{”和“}”,则抓取 {...} 内的所有字符

Grab all characters inside {...} if not contain "{" and "}"

我想捕获 { ... },

中的所有字符

如果里面没有找到“{”和“}

例如:

{amdnia91(\+wowa}

抓住它。

{amdn{ia91(\+wowa}

未捕获(包含“{”)。

preg_match_all('#(.+?)\{(.+?)\}#', $input, $output);

如何解决?

编辑。 更多解释:

我将尝试创建 css 压缩器。 但是我需要捕获括号内的所有名称和内容作为单独的数组值。

当前 $input 看起来像这样:

.something{property:value;prop2:value}#something2{someprop:val;prop:val}

它也经过精简,因此包含多个 ...{}...{} 内联。 我的代码很好,但是...... 这个 catch if inside brackets its brackets, 但如果里面包含括号,我不想抓住它。

我正在发布 daiscog 发布的正则表达式的替代方案,基于匹配我们不需要的内容并省略它的概念,并且仅在 PCRE (*SKIP)(*FAIL) 动词的帮助下匹配我们需要的内容:

[#.]?[^{}]*{[^{}]*[{}][^{}]*}(*SKIP)(*F)|[#.]?[^{}]*{([^{}]+)}

regex demo

匹配什么?

  • [#.]?[^{}]*{[^{}]*[{}][^{}]*}(*SKIP)(*F) - 可选的 .#(参见 [#.]?)后跟 {} 以外的 0+ 个字符(请参阅 [^{}]*)后跟 {,然后再跟 [^{}]*,然后是 {}(请参阅 [{}])然后又是 [^{}]* 和结束语 }。这部分匹配 .something{ 之类的字符串或什么都不匹配。然后,一旦匹配,从由于 (*SKIP)(*FAIL) 动词返回的匹配项中丢弃该匹配项。
  • | - 或者...
  • [#.]?[^{}]*{([^{}]+)} - 可选的 .#(参见 [#.]?)后跟 {} 以外的 0+ 个字符(参见 [^{}]*),然后是 {,然后是大括号以外的 1+ 个字符 ([^{}]+) 和一个右大括号 }。这是我们将保留并作为匹配项获得的内容。

PHP demo:

$re = '~[#.]?[^{}]*{[^{}]*[{}][^{}]*}(*SKIP)(*F)|[#.]?[^{}]*{([^{}]+)}~'; 
$str = "{amdnia91(+wowa}\n{amdn{ia91(+wowa}\n.something{property:value;prop2:value}#something2{someprop:val;prop:val}\n.something{property:value{;prop2:value}#something2{someprop:val;prop:val}\n.something{property:v}alue;prop2:value}#something2{someprop:val;prop:val}"; 
preg_match_all($re, $str, $matches);
print_r($matches);

结果:

Array
(
    [0] => Array
        (
            [0] => {amdnia91(+wowa}
            [1] => 
.something{property:value;prop2:value}
            [2] => #something2{someprop:val;prop:val}
            [3] => #something2{someprop:val;prop:val}
            [4] => #something2{someprop:val;prop:val}
        )

    [1] => Array
        (
            [0] => amdnia91(+wowa
            [1] => property:value;prop2:value
            [2] => someprop:val;prop:val
            [3] => someprop:val;prop:val
            [4] => someprop:val;prop:val
        )

)

[^}{] 表示匹配任何不是 } 或 {.

的字符

所以:

preg_match_all('#\{([^}{]+)\}#', $input, $output);

但是,请注意,在您的 {amdn{ia91(+wowa} 示例中,此 匹配 ia91(+wowa 片段。

编辑

如果您根本不想要第二个示例的任何匹配项,请尝试以下操作:

preg_match_all('#^[^}{]*\{([^}{]+)\}[^}{]*$#', $input, $output);

正则表达式分解意味着:

  • ^ - 行首
  • [^}{]* - 任何不是 { 或 } 零次或多次的字符
  • \{ - 文字 { 字符
  • ([^}{]+) - 捕获一个或多个不是 { 或 }
  • 的字符
  • \} - 文字 } 字符
  • [^}{]* - 任何不是 { 或 } 零次或多次的字符
  • $ - 行尾

Demonstration

第二次编辑

鉴于您对所需内容的进一步解释,我建议:

preg_match_all('#(?<=^|})[^}{]*?\{([^}{]+?)\}(?=[^}]*$|[^}]*\{)#', $input, $output);

这使用了一个 "look-behind" 和一个 "look-ahead"。分解一下,意思是:

  • (?<=^|}) 回顾:断言这是行的开头或前一个字符是文字​​ '}' 但不要将该字符作为整个匹配的一部分
  • [^}{]*? - 延迟匹配零个或多个不是 { 或 }
  • 的字符
  • \{ - 文字 {
  • ([^}{]+?) - 延迟捕获一个或多个不是 { 或 }
  • 的字符
  • \} - 文字 }
  • (?=[^}]*$|[^}]*\{) - 前瞻:确保以下字符是零个或多个不是 } 的字符后跟行尾,或者零个或多个不是 } 的字符后跟文字 { 但不要将这些字符作为整个匹配的一部分

Demonstration