樣式比對 : define ??

edited 十月 2013 in 進階PHP討論
之前問了半天,才有高手回答下面這個樣式:
/define *\( *[\'"](.*?)[\'"] *, *[\'"](.*?)[\'"] *\) *;/is

這個樣式可以透過 preg_match 找出下面結構的句子:
define('_MI_LANG_TOOL_NAME', '語言工具1');
define( '_MI_LANG_TOOL_NAME'         , '語言工具2'         );
define("_MI_LANG_TOOL_NAME",   '語言



\'\'\'\'"工具3');
define('_MI_LANG_TOOL_NAME', '語言工具4'   );
define(  '_MI_LANG_TOOL_NAME', '語言工具5' );
                            define               ('_MI_LANG_TOOL_NAME', '語言工具6');
define('_MI_LANG_TOOL_NAME', '語言工具7');
 define ( '_MI_LANG_TOOL_NAME'  , '語言工具8' ) ;
 define('_MI_LANG_TOOL_NAME', '語言工具9');

目前用來分析一些語言檔案,進行翻譯工作。但是世界並沒有那麼美好...,許多神奇的開發人員會在語言檔案加入程式邏輯,像這樣:
if($_POST['news']) define('_MI_LANG_TOOL_NAME', '語言工具1');
else define('_MI_LANG_TOOL_NAME', '我的工具');

這時候判斷就可能出問題,因為同樣的索引值會造成衝突。曾經有想過把這些非屬於語系定義的字串都獨立出來,並且標示位置,在完成翻譯後插入語系檔案中,但是還沒有實做 :-D

有人想的出怎麼做嗎?

原始討論: http://twpug.net/x/modules/newbb/viewtopic.php?topic_id=451

評論

  • edited 三月 2005
    給個範例檔,並請把你想做到的效果再敘述清楚一點!

    因為從你貼的範例來看,有蠻多想像空間的,怕我會猜錯!

    而且,我也不知道 define 放在條件示裡, 為什麼會有解析的困難 ?
  • edited 三月 2005
    http://dev.xoops.org/modules/xfmod/project/?lang_tool

    這是我寫的一個單純模組,可以翻譯XOOPS的語系檔案;但是當語系檔案包含指定語法以外的程式碼,就有可能發生錯誤的判斷。
  • edited 三月 2005
    嗯,慢慢推敲看看!
  • edited 三月 2005
    瞭解你的意思了!
    不錯哦,這支程式寫的很棒,先給你拍拍手!
    這個問題我再找時間Try看看,應該可以解決的,就是把match位置暫存,再將取代結果寫回原位置 (Regular 裡的 () 用法).

    你的檔案都是utf-8的,我為了測試,又再轉了一次big5,其中發現一些問題:
    1.lang_tool\admin\index.php 這支程式不屬於語系檔之一,但因為你加了一些中文註解,結果讓這支程式也變成utf-8編碼,會造成一些困擾!

    2.lang_tool\admin\function.php 這支程式也是utf-8編碼,但檔頭是16進位 FE FE FE FE, 轉換後會多出一個 3F. 這四個FE是怎麼多出來的?

    3.我試翻了幾支程式,有的中文寫入後,在big5編碼檢視下的網頁上看是正常的,但寫入的新php檔,檔頭也是多了 FE FE (ultraedit 會無法正常顯示中文), 但有的又不會, 所以程式裡應該還夾藏不該有的碼!

    我知道你堅持只使用utf-8, 但很多人已經掛了big5版,所以還是得考量一下big5 的使用者!
  • edited 三月 2005
    已完成,已回寄給你!

    修改如下:

    開啟 modules/lang_tool/index.php

    找到:
    switch($_POST['step']){
      case 5:
        $dir1 = XOOPS_ROOT_PATH.'/modules/'.$_SESSION['lang_tool_module'].'/language';
        $dir2 = $dir1.'/'.$_SESSION['lang_tool_to'];
        $file1 = $dir2.'/'.$_SESSION['lang_tool_file'];
        $file2 = XOOPS_ROOT_PATH.'/cache/'.$_SESSION['lang_tool_file'];
        if(is_writeable($dir1)){
          if(!file_exists($dir2))
            mkdir($dir2);
          $tgt_file = $file1;
        } else {
          $tgt_file = $file2;
        }
        array_shift($_POST);
        $fh = fopen($tgt_file, 'wb');
        fwrite($fh, '<?php'.chr(13).chr(10));
        while(list($key, $val) = each($_POST)){
          $string = 'define(\''.$key.'\', \''.addslashes($val).'\');'.chr(13).chr(10);
          fwrite($fh, $string);
        }
        fwrite($fh, '?>');
        fclose($fh);
        $content .= _MD_LANG_TOOL_YOUCANFIND. $tgt_file;
      break;
    

    替換成:
    switch($_POST['step']){
      case 5:    
        $dir1 = XOOPS_ROOT_PATH.'/modules/'.$_SESSION['lang_tool_module'].'/language';
        $dir2 = $dir1.'/'.$_SESSION['lang_tool_to'];
        $file1 = $dir2.'/'.$_SESSION['lang_tool_file'];
        $file2 = XOOPS_ROOT_PATH.'/cache/'.$_SESSION['lang_tool_file'];
        if(is_writeable($dir1)){
          if(!file_exists($dir2))
            mkdir($dir2);
          $tgt_file = $file1;
        } else {
          $tgt_file = $file2;
        }
        array_shift($_POST);
        
        $file_from = XOOPS_ROOT_PATH.'/modules/'.$_SESSION['lang_tool_module'].'/language/'.$_SESSION['lang_tool_from'].'/'.$_SESSION['lang_tool_file'];
        $source_str = file_get_contents($file_from);
        
        $pattern = '/define *\( *[\'"](.*?)[\'"] *, *[\'"](.*?)[\'"] *\) *;/is';
      
        $translated_str=preg_replace_callback($pattern,'lang_trans',$source_str);    
        
        $fh = fopen($tgt_file, 'wb');
        fwrite($fh, $translated_str);
        fclose($fh);
        $content .= _MD_LANG_TOOL_YOUCANFIND. $tgt_file;
      break;
    

    另外再新增一個function:
    function lang_trans($matches) {  
        return 'define(\''.$matches[1].'\', \''.addslashes($_POST[$matches[1]]).'\');';
    }
    

    你試試看,我這邊是OK,原始檔所有該保留的都不會更動到!
  • edited 三月 2005
    帥喔,原來有 preg_replace_callback 這個好用的函式 :-D

    越來越完整了,感謝

    ├117┤
  • edited 三月 2005
    我原先也不知道,查函數表時剛好看到,賓果 :-D
    少寫了好幾行程式 ├146┤
  • edited 三月 2005
    恩...這個樣式還是無法適用於神奇的人類...我改成這個樣了
    $pattern = '/define\s*\(\s*[\'"](.*?)[\'"]\s*,[\sA-Z\.]*[\'"](.*?)[\'"][\sA-Z\.]*\)\s*;/is';

    因為之前遇到有TAB字元在其中,所以改了一下;但還是會遇到奇怪的情形,像是單、雙引號同時使用,這個就敗北了...

    看來微積分被當真的是事實......
  • edited 三月 2005
    把這個神奇的語法貼上來看看好嗎?

    我微積分也有被當,因為一開始就懷疑在無窮小的區間內難道不會發生神奇的事嗎? 所以在無法相信他理論的絕對性之前,就學不下去了 :-?
  • edited 三月 2005
    1.
    define('EMAIL_SUBJECT', 'Message from ' . STORE_NAME);
    define('EMAIL_SEPARATOR', '----------------------------------------------------------------------------------------');
    

    2.
    define('HTML_PARAMS','dir="ltr" lang="de"');
    

    目前這兩個很好玩,我只要改出一個,另外一個就出問題...
  • edited 三月 2005
    哈哈,可惡,居然有這種偷吃步的方式:
    foreach ($lines as $line) {
    			if (substr($line,0,6) == 'define') {
    				$line = preg_split("/',\s*'/",substr($line,8,-3));
    				$constants[$line[0]] = $line[1];
    			}
    		}
    

    http://cvs.sourceforge.net/viewcvs.py/exponent/modules/modules/translatormodule/class.php?view=markup

    只是這樣子超過一行就會有問題了,繼續苦惱

    ├149┤
Sign In or Register to comment.