Parsing s-expressions with PHP
Well, I need to parse 2 textfiles. 1 named Item.txt and one named Message.txt They are configuration files for a game server, Item contains a line for each item in the game, and Message has Item names, descriptions, server messages etc. I know this is far less than ideal, but I can't change the way this works, or the format.
The idea is in Item.txt I have lines in this format
(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) )
If I have the php variable $item
which is equal to 397 (Index), I need to first get the 'name' (597).
Then I need to open Message.txt and find this line
( itemname 597 "Blue Box")
Then return "Blue Box" to PHP as a variable.
What I'm trying to do is return the item's name with the item's Index.
I know this is probably something really basic, but I've searched though dozens of file operation tutorials and still can't seem to find what I need.
Thanks
Following method doesn't actually 'parse' the files, but it should work for your specific problem...
(Note: not tested)
Given:
$item = 397;
open Item.txt:
$lines = file('Item.txt');
search index $item
and get $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');
open Message.txt:
$lines = file('Message.txt');
search $name
and get $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
should now contain Blue Box
:
echo $msg;
Not sure if your problem is with parsing the expressions, or reading files per se since you mention "file operation tutorials".
Those parenthetical expressions in your files are called s-expressions. You may want to google for an s-expression parser and adapt it to php.
You should look into the serialize function, which allows data to be stored to a textfile in a format that PHP can reinterpret easily when it needs to be reloaded.
Serializing this data as an array and saving it down to the textfiles would allow you to access it by array keys. Let's take your example. As an array, the data you described would look something like this:
$items[397]['name'] = 'bluebox';
Serializing the item array would put it in a format that could be saved and later accessed.
$data = serialize($items);
//then save data down to the text files using fopen or your favorite class
You could then load the file and unserialize it's contents to end up with the same array. The serialize and unserialize functions are directly intended for this application.
the first text file has several features that you can use to help parse it. It is up to you to decide if it is well formed and reliable enough to key on.
I noticed:
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
A method:
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.
精彩评论