Search code examples
phps-expression

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


Solution

  • 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;