解析PHP中的动态文本列表的最佳方法 [英] Best way to parse a dynamic text list in PHP

查看:53
本文介绍了解析PHP中的动态文本列表的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在文字列表下方,它来自一个流行的在线游戏,称为《 EVE Online》,当您在游戏中杀死一个人时,它基本上会被邮寄给您.我正在构建一个使用PHP解析这些信息以提取所有相关信息的工具.我将需要显示所有信息,并且正在编写类以将其很好地分解为相关的封装数据.

I have below a list of text, it is from a popular online game called EVE Online and this basically gets mailed to you when you kill a person in-game. I'm building a tool to parse these using PHP to extract all relevant information. I will need all pieces of information shown and i'm writting classes to nicely break it into relevant encapsulated data.

2008.06.19 20:53:00

Victim: Massi
Corp: Cygnus Alpha Syndicate
Alliance: NONE
Faction: NONE
Destroyed: Raven
System: Jan
Security: 0.4
Damage Taken: 48436

Involved parties:

Name: Kale Kold
Security: -10.0
Corp: Vicious Little Killers
Alliance: NONE
Faction: NONE
Ship: Drake
Weapon: Hobgoblin II
Damage Done: 22093

Name: Harulth (laid the final blow)
Security: -10.0
Corp: Vicious Little Killers
Alliance: NONE
Faction: NONE
Ship: Drake
Weapon: Caldari Navy Scourge Heavy Missile
Damage Done: 16687

Name: Gistatis Tribuni / Angel Cartel
Damage Done: 9656

Destroyed items:

Capacitor Power Relay II, Qty: 2
Paradise Cruise Missile, Qty: 23
Cataclysm Cruise Missile, Qty: 12
Small Tractor Beam I
Alloyed Tritanium Bar, Qty: 2 (Cargo)
Paradise Cruise Missile, Qty: 1874 (Cargo)
Contaminated Nanite Compound (Cargo)
Capacitor Control Circuit I, Qty: 3
Ballistic Deflection Field I
'Malkuth' Cruise Launcher I, Qty: 3
Angel Electrum Tag, Qty: 2 (Cargo)

Dropped items:

Ballistic Control System I
Shield Boost Amplifier I, Qty: 2
Charred Micro Circuit, Qty: 4 (Cargo)
Capacitor Power Relay II, Qty: 2
Paradise Cruise Missile, Qty: 10
Cataclysm Cruise Missile, Qty: 21
X-Large Shield Booster II
Cataclysm Cruise Missile, Qty: 3220 (Cargo)
Fried Interface Circuit (Cargo)
F-S15 Braced Deflection Shield Matrix, Qty: 2
Salvager I
'Arbalest' Cruise Launcher I
'Malkuth' Cruise Launcher I, Qty: 2

我正在考虑使用正则表达式解析数据,但是您将如何处理呢?您是将邮件折叠成一个单行字符串还是解析数组中的每一行?问题是有一些异常需要解决.

I'm thinking about using regular expressions to parse the data but how would you approach this? Would you collapse the mail into a one line string or parse each line from an array? The trouble is there are a few anomalies to account for.

首先,参与方:"部分是动态的,可以包含许多具有与下面类似结构的人,但是如果计算机控制的敌人也向受害者开枪,它会缩短为名称"和损坏完成"字段,如上图所示(Gistatis Tribuni/Angel Cartel).

First, the 'Involved parties:' section is dynamic and can contain lots of people all with the similar structure as below but if a computer controlled enemy takes a shot at the victim too, it gets shortened to only the 'Name' and 'Damage Done' fields, as shown above (Gistatis Tribuni / Angel Cartel).

第二,销毁"和丢弃"项目是动态的,每封邮件的长度是不同的,我还需要获取数量,无论是否装在货物中.

Second, the 'Destroyed' and 'Dropped' items are dynamic and will be different lengths on each mail and i will also need to get the quantity and wether or not they are in cargo.

欢迎您提出想法.

推荐答案

如果您想要一些灵活的方法,请使用状态机方法.

If you want something flexible, use the state machine approach.

如果您想要快速又脏的东西,请使用regexp.

If you want something quick and dirty, use regexp.

对于第一个解决方案,您可以使用专用于parsin的库,因为这不是一件容易的事.但是,因为它的格式非常简单,所以您可以破解朴素的解析器,例如:

For the first solution, you can use libraries that are specialized in parsin since it's not a trivial task. But because it's fairly simple format, you can hack a naive parser, as for example :

<?php

class Parser 
{
   /* Enclosing the parser in a class is not mandatory but it' clean */

    function Parser()
    {

        /* data holder */
        $this->date = '';
        $this->parties = array();
        $this->victim = array();
        $this->items = array("Destroyed" => array(),
                                            "Dropped" => array());

        /* Map you states on actions. Sub states can be necessary (and sub parsers too :-) */                   
        $this->states = array('Victim' => 'victim_parsing',
                                             'Involved' => 'parties_parsing' ,
                                             'items:' => "item_parsing");


        $this->state = 'start';                      
        $this->item_parsing_state = 'Destroyed';     
        $this->partie_parsing_state = '';           
        $this->parse_tools = array('start' => 'start_parsing',
                                           'parties_parsing' =>'parties_parsing',
                                           'item_parsing' => 'item_parsing',
                                           'victim_parsing' => 'victim_parsing');


    }

    /* the magic job is done here */

    function checkLine($line) 
    {
        foreach ($this->states as $keyword => $state) 
            if (strpos($line, $keyword) !== False)
                    $this->state = $this->states[$keyword];

        return trim($line);
    }

    function parse($file)
    {
        $this->file = new SplFileObject($file);
        foreach ($this->file as $line) 
            if ($line = $this->checkLine($line))
                 $this->{$this->parse_tools[$this->state]}($line);
    }


    /* then here you can define as much as parsing rules as you want */

    function victim_parsing($line) 
    {
        $victim_caract = explode(': ', $line);
        $this->victim[$victim_caract[0]] = $victim_caract[1];
    }

    function start_parsing($line)
    {
        $this->date = $line;
    }

    function item_parsing($line) 
    {
        if (strpos($line, 'items:') !== False)
        {
            $item_state = explode(' ', $line);
            $this->item_parsing_state = $item_state[0];
        }   
          else 
         {
               $item_caract = explode(', Qty: ', $line);
               $this->items[$this->item_parsing_state][$item_caract[0]] = array();
               $item_infos =  explode(' ', $item_caract[1]);
               $this->items[$this->item_parsing_state][$item_caract[0]] ['qty'] = empty($item_infos[0]) ? 1 : $item_infos[0];
               $this->items[$this->item_parsing_state][$item_caract[0]] ['cargo'] = !empty( $item_infos[1]) ? "True":  "False";
               if  (empty( $this->items[$this->item_parsing_state][$item_caract[0]] ['qty'] ))
                print $line;
         }
    }

    function parties_parsing($line) 
    {        

        $partie_caract = explode(': ', $line);

        if ($partie_caract[0] == "Name")
        {
            $this->partie_parsing_state = $partie_caract[1];
            $this->parties[ $this->partie_parsing_state ] = array();
        }
        else
            $this->parties[ $this->partie_parsing_state ][$partie_caract[0]] = $partie_caract[1];

    }

}

/* a little test */

$parser = new Parser();
$parser->parse('test.txt');

echo "======== Fight report - ".$parser->date." ==========\n\n";
echo "Victim :\n\n";
print_r($parser->victim);
echo "Parties :\n\n";
print_r($parser->parties);
echo "Items: \n\n";
print_r($parser->items);

?>

我们可以这样做,因为在这里,可靠性和性能不是问题:-)

We can do that because here, reliability and perf are not an issue :-)

游戏愉快!

这篇关于解析PHP中的动态文本列表的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆