Рекурсивное регулярное выражение с искаженным текстом? Получение "ArrayArray"

Я задал аналогичный вопрос, но он был закрыт для того, чтобы быть слишком широким. В принципе, у меня есть куча вопросов вроде этого. Я надеюсь, что просто спросить, будет легче. Я пробовал несколько способов решить эту проблему, но никто из них не работает.

У меня есть текстовый файл с большим количеством данных. Единственные данные, которые меня интересуют, попадают между двумя скобками "(" ")". Мне интересно, как получить каждый экземпляр информации, которая находится между скобками в массив.

Код, который я использую прямо сейчас, возвращает ArrayArray :

 function get_between($startString, $endString, $myFile){ preg_match_all('/\$startString([^$endString]+)\}/', $myFile, $matches); return $matches; } $myFile = file_get_contents('explode.txt'); $list = get_between("&nbsp(", ")", $myFile); foreach($list as $list){ echo $list; } 

 <?php function get_between($startString, $endString, $myFile){ //Escape start and end strings. $startStringSafe = preg_quote($startString, '/'); $endStringSafe = preg_quote($endString, '/'); //non-greedy match any character between start and end strings. //s modifier should make it also match newlines. preg_match_all("/$startStringSafe(.*?)$endStringSafe/s", $myFile, $matches); return $matches; } $myFile = 'fkdhkvdf(mat(((ch1)vdsf b(match2) dhdughfdgs (match3)'; $list = get_between("(", ")", $myFile); foreach($list[1] as $list){ echo $list."\n"; } 

Я сделал это и, похоже, сработал. (Очевидно, вам нужно будет заменить строку назначения myFile вашим заявлением file_get_contents.) Несколько вещей:

A: Переменная замена не будет происходить с одиночными кавычками. Таким образом, ваше регулярное выражение preg_replace_all не будет работать. Поскольку это буквально добавляет $ startString к вашему выражению вместо (. (Я также удалил проверку) в конце строки с совпадением. Добавьте его обратно, если вам это нужно с \\} непосредственно перед окончательным разделителем.)

B: $ list будет массивом массивов. По-моему, по умолчанию индекс нуля будет содержать все полные совпадения. index one будет содержать первое соответствие подшаблонов.

C: Это работает только до тех пор, пока $ endString никогда не будет найден внутри подшаблона, который вы пытаетесь сопоставить. Скажем, если вы ожидаете (matc (fF)) дать вам matc (fF), это не произойдет. Это даст вам соответствие (fF. Вам понадобится более мощный парсер, если вы хотите получить прежний результат в этом случае.

Изменить: здесь функция get_between должна работать с &nbsp;( и )} а также, что бы вы ни хотели.

Ваше регулярное выражение полностью введено в заблуждение.

Во-первых: [^...] является дополняемым классом символов. Дополненный класс символов – это атом, а любой ... есть набор символов, которые нельзя допускать в этот момент. Т.е., [^ab] позволит что угодно, кроме a и b .

Во-вторых: вы, кажется, хотите, чтобы иметь возможность захвата между parens. Но парень (открытый или закрывающий) является особым символом в регулярном выражении. Итак, в вашем примере, если $startString is &nbsp( , этот параметр будет интерпретироваться как метасимвол регулярного выражения.

Третье: к сожалению, это невозможно решить с помощью регулярных выражений, но вложенные $startString и $endString не могут быть сопоставлены (ну, они могут с perl, но perl perl).

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

 $start = preg_quote($startString, '/'); $end = preg_quote($endString, '/'); $re = '/\Q' . $start . '\E' # literal $start . '(' # capture... . '(?:(?!\Q' . $end . '\E).)' # any character, as long as $end is not found at this position, . '+)' # one or more times . '\Q' . $end . '\E/'; # literal $end 

а затем использовать это как ваш первый аргумент для preg_match_all .

Модификаторы \Q и \E regex говорят, что все, что находится между первым и вторым, должно рассматриваться как литералы – следовательно, парн в &nbsp( будет обрабатываться буквально, а не как метасимвол открытия группы.