Регулярные выражения: получите то, что находится за скобками - PullRequest
2 голосов
/ 15 сентября 2010

Я использую PHP, и у меня есть текст как:

first [abc] middle [xyz] last

Мне нужно получить то, что внутри и снаружи скобок. Выполняя поиск в StackOverflow, я нашел шаблон, чтобы получить то, что внутри:

preg_match_all('/\[.*?\]/', $m, $s)

Теперь я хотел бы знать схему, чтобы получить то, что снаружи.

* * 1008 Привет! * * 1009

Ответы [ 4 ]

4 голосов
/ 15 сентября 2010

Вы можете использовать preg_split для этого как:

$input ='first [abc] middle [xyz] last';
$arr = preg_split('/\[.*?\]/',$input);
print_r($arr);

Вывод:

Array
(
    [0] => first 
    [1] =>  middle 
    [2] =>  last
)

Это позволяет некоторые окружающие пробелы в выводе.Если вы не хотите их использовать, вы можете использовать:

$arr = preg_split('/\s*\[.*?\]\s*/',$input);

preg_split разбивает строку на основе шаблона.Шаблон здесь [, за которым следует что-либо, за которым следует ].Регулярное выражение для сопоставления с чем угодно - .*.Также [ и ] являются регулярными выражениями meta char, используемыми для класса char.Поскольку мы хотим сопоставить их буквально, нам нужно избежать их, чтобы получить \[.*\]..* по умолчанию является жадным и постарается найти максимально возможное совпадение.В этом случае оно будет соответствовать abc] middle [xyz.Чтобы избежать этого, мы делаем его не жадным, добавляя его с ?, чтобы дать \[.*?\].Поскольку наше определение чего-либо здесь на самом деле означает что-то отличное от ], мы также можем использовать \[[^]]*?\]

EDIT:

Если вы хотите извлечь слова, которые одновременновнутри и снаружи [] вы можете использовать:

$arr = preg_split('/\[|\]/',$input);

, которые разбивают строку на [ или ]

2 голосов
/ 15 сентября 2010

Используйте preg_split вместо preg_match.

preg_split('/\[.*?\]/', 'first [abc] middle [xyz] last');

Результат:

array(3) {
  [0]=>
  string(6) "first "
  [1]=>
  string(8) " middle "
  [2]=>
  string(5) " last"
}

ideone

1 голос
/ 16 сентября 2010

Поскольку каждый говорит, что вы должны использовать preg_split, но только один человек ответил с выражением, которое соответствует вашим потребностям, , и я думаю, что это немного сложно - не сложно, немного многословно, но он обновил свой ответ, чтобы противостоять этому.

Это выражение - то, о чем говорилось в большинстве ответов.

/\[.*?\]/

Но это только распечатывает

Array
(
    [0] => first 
    [1] =>  middle 
    [2] =>  last
)

и вы заявили, что хотите что-то внутри и за скобками, sio обновление будет:

/[\[.*?\]]/

Это дает вам:

Array
(
    [0] => first 
    [1] => abc
    [2] =>  middle 
    [3] => xyz
    [4] =>  last
)

но, как вы видите, он также захватывает пробелы, поэтому давайте сделаем еще один шаг и избавимся от них:

/[\s]*[\[.*?\]][\s]*/

Это даст вам желаемый результат:

Array
(
    [0] => first
    [1] => abc
    [2] => middle
    [3] => xyz
    [4] => last
)

Я думаю, это то выражение, которое вы ищете.

Вот прямая демонстрация вышеупомянутого регулярного выражения

1 голос
/ 15 сентября 2010
$inside = '\[.+?\]';
$outside = '[^\[\]]+';
$or = '|';

preg_match_all(
    "~ $inside $or $outside~x", 
    "first [abc] middle [xyz] last", 
    $m);
print_r($m);

или менее подробный

  preg_match_all("~\[.+?\]|[^\[\]]+~", $str, $matches)
...