2016-04-18 4 views
2

Я хочу, чтобы поймать всех символов внутри { ... },захватить все символы внутри {...}, если они не содержат «{» и «}»

Если внутри не найден «{» и «}»

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

{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 так containt несколько ... {} ... {} инлайн. И мой код поймать все хорошо, но ... Этот улов также, если внутри скобки его скобки, , но я не хочу улавливать его, если они содержат скобки внутри.

+3

значит, вы не хотите, чтобы соответствовать вообще, если есть '' {внутри '{...} '? Даже не часть его? –

+0

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

+1

Позвольте пояснить: [это] (https://regex101.com/r/wT2jZ2/1) ОК? Ответ на daiscog почти такой же. –

ответ

3

[^}{] означает любой символ, который не является} или {.

Итак:

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

Однако, обратите внимание, что в вашем {amdn{ia91(+wowa} примере это будет соответствовать ia91(+wowa фрагмент.

EDIT

Если вы не хотите ни одного матча на всех для этого второго примера, попробуйте следующее:

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

регулярное выражение разбитые средства:

  • ^ - Начало линии
  • [^}{]* - Любой символ whic ч не {или} ноль или более раз
  • \{ - Буквальный {характер
  • ([^}{]+) - Захват одного или нескольких символов, которые не являются {или}
  • \} - Буквальный} символов
  • [^}{]* - Любой символ, который не является {или} ноль или более раз
  • $ - конец линии

Demonstration

Второй Редактировать

Учитывая ваше дальнейшее объяснение того, что вам нужно, я предлагаю следующее:

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

Это использует «Двойник за» и «прогностический».Сломался, это означает:

  • (?<=^|}) касательно предшествующий текст: Утверждает, что это либо начало линии или что предыдущий символ был буквальным «}» , но не включает в себя этот символ как часть всего матча
  • [^}{]*? - Лениво соответствует нулю или более символов, которые не являются {или}
  • \{ - буквальный {
  • ([^}{]+?) - Лениво захватить один или несколько символов, которые не являются {или}
  • \} - Литералом}
  • (?=[^}]*$|[^}]*\{) - Lookahead: Убедитесь, что следующие символы являются либо ноль или более символов, которые не являются} следуют в конце линии, или ноль или больше символов, которые не являются} с последующим буквальным {но не включают в себя такие символы, как часть всего матча

Demonstration

+0

https://regex101.com/r/oK9xT4/1 - не знаю, если это ожидается. На самом деле, нет смысла в ленивом квантере , он работает так же, как и жадный. –

+0

Правда, я удалю его – megaflop

+0

@daiscog. Но я хочу получить $ output только в том случае, если в скобках не найдены другие скобки. – KsaR

2

Я отправляю альтернативу регулярного выражения, которое разместили 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 
     ) 

) 
+0

Я восстановил свой ответ, так как [вы подтверждаете] (http://stackoverflow.com/questions/36691046/grab-all-characters-inside-if-not-contain-and/36691098#comment60970884_36691046), который вы хотите совместить 'ia91 (+ wowa' внутри '{amdn {ia91 (+ wowa}'. Вот [demo] (https://regex101.com/r/wT2jZ2/1) моего регулярного выражения. –

+0

Здесь вам понадобится ленивый квантификатор, else '{abc} def}' будет соответствовать 'abc} def' в группе захвата – megaflop

Смежные вопросы