2010-12-17 3 views
1

мне нужно изменить что-то вроде этого:PHP Simple Regex

' . $scripturl . ' '.$scripturl.' ' .$scripturl .' '.$context['forum_name'].'

В основном, количество пробелов в между ' и . и $ не имеет значения, он должен чтобы все это начиналось с ' и заменяло его либо {$scripturl}, либо {$context[forum_name]}

Кроме того, он должен сделать это (фигурные скобки) для каждой переменной $ КРОМЕ для этих переменных: $txt и $helptxt

Как я могу это сделать с помощью preg_replace?

EDIT Я читаю файл PHP, в котором определены значения массива. Я использую $data = get_file_contents(file);, чем мне нужно Regex, чтобы изменить все переменные, определенные в этом файле, с $ перед словом, EXCEPT $ txt и $ helptxt variables, и мне нужно, чтобы эти переменные + '. или ' ., что перед переменной или в конце. Пример строки в этом файле может быть так:

$txt['dp_who_forum'] = 'Viewing the forum index of <a href="' . $scripturl . '?action=forum">' .$context['forum_name'].'</a>.'; 

Так что нужно будет его заменить на это, вместо того, чтобы:

$txt['dp_who_forum'] = 'Viewing the forum index of <a href="{$scripturl}?action=forum">{$context[forum_name]}</a>.'; 

Как это можно сделать? И мне также нужно исключить из этого переменные $ helptxt.

+2

я не уверен, что здесь спрашивают. Не могли бы вы начать с вершины? Может быть, объясните, что вы делаете? – Stephen 2010-12-17 04:31:45

+0

Хорошо, отредактированный вопрос, надеюсь, поможет вам понять, что я пытаюсь сделать. – SoLoGHoST 2010-12-17 04:40:18

ответ

1

Хотя я не 100% уверен, что вы спрашиваете, я думаю, что это будет делать то, что вы хотите:

preg_replace(
    '/ 
    \'\h*\.\h*       # Match a quote and a dot 
    (\$(?!(?:help)?txt\b)    # Avoid matching $txt or $helptxt... 
     \w+)(?:(\[)([\'"])(\w+)\3(\]))? # ...but do match $var or $arr["idx"] 
    \h*\.\h*\'       # Match a quote and a dot 
    /x', 
    '{$1$2$4$5}', 
    $string) 

для комментариев помощи, но регулярное выражение по-прежнему выглядит как Ктулху ругань, так что давайте перерыв это на куски. Регулярное выражение окружено разделителями /, которые находятся там, потому что preg_replace требует их. /x в конце позволяет нам вставлять пробелы и комментарии в регулярное выражение, которое мы используем, чтобы сделать его более понятным. Заклинание \'\h*\.\h*, которое появляется в начале и в конце, соответствует ' . и тому подобное. (Если вы хотите совместить одиночные или двойные кавычки, замените \' на [\'"].) ' нужно экранировать только с \, потому что мы в одной кавычки. \h указывает любое горизонтальное пробельное пространство (в значительной степени пространство или вкладку), с *, допускающим любое число. Затем \. - буква ., а \h* - больше места.

Во второй строке мы начинаем сопоставлять переменную, которую мы помещаем в группу 1 с круглыми скобками. Сначала мы сопоставляем \$, буквальный знак доллара, а затем мы используем (?!(?:help)?txt\b). Интерьер прост: (?:help)? необязательно соответствует help (?:), а затем мы сопоставляем txt, а затем \b, который заставляет сломать слот (так что $txta все еще соответствует). (?!...) является отрицательным взглядом: он не потребляет никакого ввода, но соответствует только если его внутренняя часть не.Таким образом, мы можем здесь только соответствовать, если имя переменной неtxt или helptxt.

На третьей строке мы заканчиваем сопоставление переменной. \w+ просто соответствует одному или нескольким «символам слов»: alphanumerics и подчеркиванию. После этого мы сохраняем имя переменной для захвата группы 1 - без индекса массива, если есть один! Затем мы сопоставляем что-то в (?:...)?, которое просто необязательно соответствует ему, не сохраняя его в группе захвата. Интерьер соответствует ['array_access'] бит, если он существует. Мы сохраняем множество групп захвата здесь, чтобы мы могли удалять кавычки, как вы хотите. Сначала мы сопоставляем литерал [ с \[ и сохраняем его в группе 2. Затем мы сопоставляем либо одиночную, либо двойную кавычку с [\'"] и сохраняем ее в группе 3-го захвата. Затем мы сопоставляем другую строку словных символов, которая является индексом массива и сохраняет его при захвате группы 4. Затем мы сопоставляем ту цитату, с которой мы начали, сопоставляя \3, которая захватывает группу 3. Наконец, мы сопоставляем закрывающую фигуру и сохраняем ее при захвате пятой группы. Наконец, мы снова сопоставляем точку и цитату. (Если вы не хотите, чтобы соответствовать $arr["idx"], но только $arr['idx'], а затем изменить каждый из ([\'"]) и \3 к \' и измените строку замены на {$1$2$3$4}.)

Мы тогда заменить это '{$1$2$4$5}'. Если вы помните, $1 - это имя переменной (и знак доллара), $2 - [, $4 - индекс массива (без кавычек), а $5 - это ]. Либо все $2, $4, и $5 определены или не указаны, поэтому при их появлении мы получаем только квадратные скобки.

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

0

Вы можете сделать это с помощью двух проходов, один для неблокируемого стиля и один для стиля в квадратных скобках.

В скобках, заменить

'\s*\.\s*\$(?!txt|helptxt)(\w+)\['(\w+)'\]\s*\.\s*' 

с

{\$$1[$2]} 

Тогда для индексных скобок переменных, заменить

'\s*\.\s*\$(?!txt|helptxt)(\w+)\s*\.\s*' 

с

{\$$1} 

Вы должны убедиться, что вы убегаете вещи прямо в функции preg_replace

0

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

  1. Replace $ TXT & $ helptxt что-то очень странное, такие как «_WHAT_IS_THIS _1» и «_WHAT_IS_THIS _2»
  2. Заменить все $ переменные в строке
  3. Заменить "_WHAT_IS_THIS _1" от "$ .txt" и "_WHAT_IS_THIS _2" на "$ helptxt"
0
preg_replace("!\\'\\s*\\.\\s*\\$((?:([^ht]|t[^x]|tx[^t]|h[^e]|he[^l]|hel[^p]|help[^t]|helpt[^x]|helptx[^t])\\w*|helptxt\\w+|txt\\w+)(?:\\[.+?\\])?)\\s*\\.\\s*\\'!", '{$\\1}', $str) 

Регулярное выражение не просто.

+0

Ничего себе, это не так. Думал бы, что это так. Спасибо anyways :) – SoLoGHoST 2010-12-17 05:49:43

0

Это в основном выражение PHP для преобразования Smarty. Для этого простого случая и поймать все потенциальные переменные используют:

$data = preg_replace("/'[\s.]+([$]\w+)[\s.]+'/ims", '{$1}', $data); 
$data = preg_replace("/'[\s.]+([$]\w+)\['(\w+)'\][\s.]+'/ims", '{$1[$2]}', $data); 

Чтобы изменить процесс и превратить 'string ... {$var[xyz]} ...' обратно в выражение PHP 'string ... ' . $var["xyz"] . ' ...' использовать что-то вроде:

$string = var_dump($string, 1); 
$string = preg_replace('/\{([$]\w+)\}/', "' . $1 . '", $data); 
$string = preg_replace('/\{([$]\w+)\[(\w+)\]\}/', "' . $1['$2'] . '", $data);