PHP - Regex для удаления кавычек и добавления скобок? - PullRequest
2 голосов
/ 08 декабря 2010

Что ж, мне неприятно это признавать, но мне сложно с REGEX, я так и не смог найти приличное руководство по настройке выражений.

Так скажи, у меня есть что-то вроде этого

context['something']

и я хочу изменить все вхождения на

context[something] 

Тогда у меня есть

' . $var . ' 

и я хочу изменить все вхождения на

{var} 

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

Вот моя попытка.

$codes = array (
         '/(\' \. \$)(.+)( \. \')/',
        '/(\[\')(.+)(\'\])/'
);
$html = array (
        '{\\2}',
        '[\\2]',
);
$data = preg_replace($codes, $html, $data); 

Это работает до тех пор, пока вы не получите их в файле, а затем все испортится.

Это текущая настройка

// these are temp need a better replace system
$data = str_replace("' . $", "{", $data);
$data = str_replace(" . '", "}", $data);
$data = str_replace("<?php", "", $data);
$data = str_replace("?>", "", $data);
$data = str_replace('context[\'forum_name\']', 'context[forum_name]', $data); 

Просто нужен правильный способ комментировать их, чтобы они могли быть преобразованы позже во время сохранения.

Может кто-нибудь помочь, пожалуйста?

Спасибо:)

Ответы [ 3 ]

5 голосов
/ 08 декабря 2010

Сделайте ваши спички не жадные .

Изменение

.+

до

.+?

Работает !!

Пояснение:

Квантификатор + по умолчанию жадный.

Рассмотрим регулярное выражение \[(.+)\], которое пытается сопоставить и захватить все, что находится между [ и ]. На входе [foo] работает нормально и foo фиксируется. Но на входе [foo] and [bar] он будет захватывать foo] and [bar !!! Это жадное поведение в действии, которое заставляет + потреблять столько, сколько может. Делая совпадение не жадным \[(.+?)\], мы говорим + потреблять как можно меньше, но все же пытаться сопоставить. Так что в этом случае с тем же входом он будет захватывать foo.

Несколько советов:

В вашем регулярном выражении нет необходимости в 1-й и 3-й группах: '/(\' \. \$)(.+)( \. \')/'. Таким образом, вы можете сбросить 1-ю и 3-ю пару (...). Если вы просто хотите группировать, используйте (?:..) вместо (..), который используется для группировки + захвата.

Использование \\n в запасной части не рекомендуется. Он должен использоваться только как обратная ссылка в регулярном выражении. Чтобы использовать группы захвата в запасной части, используйте $n.

Программа с вышеуказанными изменениями

1 голос
/ 08 декабря 2010

Я нашел этот инструмент чрезвычайно полезным при изучении регулярных выражений.

0 голосов
/ 08 декабря 2010

Вот один из них:

preg_replace("/context\['([^\']+)'\]/", "context[$1]", "context['bob']");

вместо использования не жадного совпадения, мы просто ищем все, что не является кавычкой.

И другое:

preg_replace("/' . [$]([^ ]+) . '/", '{$1}', '\' . $foo . \'');

Это немного сложнее.Мы должны перехватить $ в наборе, чтобы он не рассматривался как символ конца строки.И {$ 1} должен быть в одинарных кавычках, чтобы PHP не интерпретировал его + фигурные скобки как переменную.

...