Я хочу поймать весь символ внутри { ... },

Если внутри не найдено "{" и "}"

Так например:

{amdnia91(\+wowa}

Лови.

{amdn{ia91(\+wowa}

Не ловить (содержать "{").

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

Как это исправить?

РЕДАКТИРОВАТЬ. Объяснил больше:

Я попробую создать css minifier. Но там мне нужно поймать все имена и содержимое внутри скобок как отдельное значение массива.

Текущий $ input выглядит так:

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

Он также минифицирован, поэтому содержит несколько ... {} ... {} встроенных. И мой код ловит все хорошо, но ... Этот улов также, если внутри квадратных скобок, но я не хочу ловить его, если внутри скобки.

2
KsaR 18 Апр 2016 в 13:13

1 ответ

Я публикую альтернативу регулярному выражению, опубликованному daiscog, на основе концепции сопоставления того, что нам не нужно, и его исключения, и сопоставляю только то, что нам понадобится позже, с помощью глаголов PCRE (*SKIP)(*FAIL):

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

См. демонстрацию регулярных выражений

С чем это связано?

  • [#.]?[^{}]*{[^{}]*[{}][^{}]*}(*SKIP)(*F) - необязательный . или # (см. [#.]?), за которым следует 0+ символов, кроме { и } (см. {{X6 }}), за которым следует {, за которым снова следует [^{}]*, за которым следует либо {, либо } (см. [{}]), а затем снова {{ X12}} и закрытие }. Эта часть соответствует строкам типа .something{ или ничего. Затем, после совпадения, отбросьте это совпадение из совпадений, возвращенных с помощью глаголов (*SKIP)(*FAIL).
  • | - или ...
  • [#.]?[^{}]*{([^{}]+)} - необязательный . или # (см. [#.]?), за которым следует 0+ символов, кроме { и } (см. {{X6 }}), затем {, затем 1+ символов, кроме фигурных скобок ([^{}]+) и закрывающей фигурной скобки }. Это то, что мы сохраним и получим в виде спичек.

Демонстрация PHP:

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

)
2
Wiktor Stribiżew 18 Апр 2016 в 20:53