抓住{...}内的所有字符,如果不包含" {"和"}"

时间:2016-04-18 10:13:04

标签: php regex pcre regex-negation

我想抓住{ ... }内的所有角色,

如果未找到内容" {"和" }"

例如:

{amdnia91(\+wowa}

抓住它。

{amdn{ia91(\+wowa}

不捕捉(包含" {")。

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

如何解决?

EDIT。 解释更多:

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

Curret $输入看起来像这样:

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

它也是minfied所以包含多个...... {} ... {} inline。 我的代码一切都很好,但...... 如果括号内有括号, 但如果内部包含括号,我不想抓住它。

2 个答案:

答案 0 :(得分:3)

[^}{]表示匹配任何非}或{。

的字符

所以:

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

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

修改

如果你不希望第二个例子有任何匹配,那么试试这个:

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

正则表达式分解意味着:

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

Demonstration

第二次修改

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

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

这使用了“后视”和“前瞻”。细分,这意味着:

  • (?<=^|}) Lookbehind:断言这是该行的开头,或者前一个字符是文字​​'}',但不包括该字符作为整个匹配的一部分
  • [^}{]*? - 懒惰地匹配零个或多个不是{或}
  • 的字符
  • \{ - 文字{
  • ([^}{]+?) - 懒惰地抓取一个或多个不是{或}
  • 的字符
  • \} - 文字}
  • (?=[^}]*$|[^}]*\{) - Lookahead:确保以下字符为零个或多个字符,不是后跟行结尾,或者是零个或多个不是字符}后面跟着文字{但是不要将这些字符作为整场比赛的一部分

Demonstration

答案 1 :(得分:2)

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

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

请参阅regex demo

它匹配什么?

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

PHP demo

[^{}]+

结果:

}