Разбор s-выражений с помощью PHP

Ну, мне нужно разобрать 2 текстовых файла. 1 с именем Item.txt и один с именем Message.txt Они являются файлами конфигурации для игрового сервера, Item содержит строку для каждого элемента в игре, а Message содержит имена элементов, описания, сообщения сервера и т. Д. Я знаю, что это гораздо меньше, чем идеально, но я не могу изменить способ, которым это работает, или формат.

Идея есть в Item.txt У меня есть строки в этом формате

(item (name 597) (Index 397) (Image "item030") (desc 162) (class general etc) (code 4 9 0 0) (country 0 1 2) (plural 1) (buy 0) (sell 4) )

Если у меня есть переменная php $item который равен 397 (индекс), мне нужно сначала получить "имя" (597).

Затем мне нужно открыть Message.txt и найти эту строку

( itemname 597 "Blue Box")

Затем верните "Blue Box" в PHP в качестве переменной.

То, что я пытаюсь сделать, это вернуть имя элемента с индексом элемента.

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

Спасибо

4 ответа

Решение

Следующий метод на самом деле не "разбирает" файлы, но он должен работать для вашей конкретной проблемы...

(Примечание: не тестировалось)

Дано:

$item = 397;

открыть Item.txt:

$lines = file('Item.txt');

поисковый индекс $item и получить $name:

$name = '';
foreach($lines as $line){ // iterate lines
    if(strpos($line, '(Index '.$item.')')!==false){
        // Index found
        if(preg_match('#\(name ([^\)]+)\)#i', $line, $match)){
            // name found
            $name = $match[1];
        }
        break;
    }
}
if(empty($name)) die('item not found');

открыть Message.txt:

$lines = file('Message.txt');

поиск $name и получить $msg:

$msg = '';
foreach($lines as $line){ // iterate lines
    if(strpos($line, 'itemname '.$name.' "')!==false){
        // name found
        if(preg_match('#"([^"]+)"#', $line, $match)){
            // msg found
            $msg = $match[1];
        }
        break;
    }
}

$msg теперь должен содержать Blue Box:

echo $msg;

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

Сериализация этих данных в виде массива и сохранение их в текстовых файлах позволит вам получить к ним доступ с помощью ключей массива. Давайте возьмем ваш пример. Как массив, описанные вами данные будут выглядеть примерно так:

$items[397]['name'] = 'bluebox';

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

$data = serialize($items);
//then save data down to the text files using fopen or your favorite class

Затем вы можете загрузить файл и десериализовать его содержимое, чтобы получить тот же массив. Функции сериализации и десериализации предназначены для этого приложения.

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

Эти выражения в скобках в ваших файлах называются s-выражениями. Вы можете поискать s-выражение и адаптировать его к php.

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

Я заметил:

1) a record is delimited by a single line break
2) the record is further delimted by a set of parens () 
3) the record is typed using a word (e.g. item)
4) each field is delimited by parens 
5) each field is named and the name is the first 'word' 
6) anything after the first word is data, delimited by spaces
7) data with double quotes are string literals, everything else is a number

Метод:

read to the end of line char and store that
strip the opening and closing parens
strip all closing )
split at ( and store in temp array (see: http://www.php.net/manual/en/function.explode.php)
element 0 is the type (e.g. item)
for elements 1-n, split at space and store in temp array.
element 0 in this new array will be the key name, the rest is data
once you have all the data compartmentalized, you can then store it in an associative array or database. The exact structure of the array is difficult for me to envision without actually getting into it.
Другие вопросы по тегам