1. 程式人生 > >使用正則表示式處理包含動態數值並支援運算的字串

使用正則表示式處理包含動態數值並支援運算的字串

背景說明

假設遊戲技能介紹中,我們需要描述技能傷害、技能冷卻時間等數值。如果需要改變一個數值,除了修改儲存的數值以外,我們還需要修改技能介紹對於這個數值的描述。有時候經常會修改了數值而忘記修改描述,造成技能的使用效果並不像其描述的那樣。

 

所以我們可以使用佔位符,再使用正則表示式做替換,並進行處理,簡化以後每一次的數值修改。只需要關心數值修改,不需要再每一次都修改描述。另外,由於我們在技能描述中的數值單位與數值在儲存單位不一定相同,所以必須要支援基本的數值運算。比如1000ms換成1秒。

 

假設技能描述是這樣的"冷卻時間:{#cd}毫秒,{#cd/1000}秒",cd的值為1000。那麼這個描述經過處理後是這樣的"冷卻時間:1000毫秒,1秒"。

 

 

程式碼

php

class Skill
{
    /**
     * 技能介紹
     */
    public $introduction="";
    /**
     * 冷卻時間 單位ms
     */
    public $cd=0;


    public function handleIntroduction()
    {
        $content=$this->introduction;
        //找出所有被{}及其包裹的內容集合
        //$matchs[0]為帶{}的集合 $matchs[1]為不帶{}的集合
        preg_match_all("/\{([^\{\}]+)\}/",$content,$matchs);
        for ($i = 0; $i < count($matchs[1]); $i++)
        {
            $math=$matchs[1][$i];
            //從包裹內容中匹配出變數名
            //$valueNames[0]為帶#的變數名 $valueNames[1]為不帶#的變數名
            preg_match_all("/\#([^\+\-\*\/0-9]+)/",$math,$valueNames);
            for ($j= 0; $j < count($valueNames[1]); $j++)
            {
                $valueName=$valueNames[1][$j];
                //getValue方法獲取相應變數名的變數值
                $value=$this->getValue($valueName);
                //替換掉{}及其包裹的內容
                $math=str_replace($valueNames[0][$j],$value,$math);
            }
            //所有變數名換成了變數值,進行運算
            $math=eval("return $math;");
            $content=str_replace($matchs[0][$i],$math,$content);
        }
        $this->introduction =$content;
    }

	private function getValue($valueName)
    {
        $value = $this->$valueName;
        if ($value != null)
        {
            return $value;
        }else{
            return 0;
        }
    }
}

呼叫

$skill=newSkill;

$skill->cd=1000;

$skill->introduction="冷卻時間:{#cd}毫秒,{#cd/1000}秒";

$skill->handleIntroduction();

print_r($skill->introduction);

//冷卻時間:1000毫秒,1秒