2010-12-08 11 views
0

Ich habe Strings, die aus einer PHP-Datei gelesen werden, zum Beispiel:PHP - RegEx Problem

<?php 
// Dream Portal (c) 2009-2010 Dream Portal Team 
// DreamPortal.english.php; @1.1 

global $scripturl, $context; 

// General Strings 
$txt['forum'] = 'Forum'; 
$txt['dream_portal'] = 'Dream Portal'; 
$txt['dp_core_modules'] = 'Collapse or Expand this Module'; 
$txt['dp_who_forum'] = 'Viewing the forum index of <a href="' . $scripturl . '?action=forum">' . $context['forum_name'] . '</a>.'; 
$txt['dp_who_portal'] = 'Viewing the portal index of <a href="' . $scripturl . '">' . $context['forum_name'] . '</a>.'; 
$txt['dp_who_page'] = 'Viewing the page &quot;<a href="' . $scripturl . '?page=%1$s">%2$s</a>&quot;.'; 
?> 

Und hier ist der REGEX, die ich zur Zeit bin mit dem tut, was ich brauche:

$data = file_get_contents('./'.$language.'/'.$file.'.'.$language.'.php'); 

$codes = array (
    '/(\' \. \$)(.+?)(\. \')/', 
    '/(\= \$)(.+?)(\. \')/', 
     '/(\' \. \$)(.+?)(\;)/', 
    '/(\[\')(.+?)(\'\])/', 
    '/<\?php/s', '/\?>/s', '/<\?/s' 
); 
$html = array (
    '{$2}', 
    '= \'{$2}', 
    '{$2}\';', 
    '[$2]', 
    '', 
); 
// Since we don't have the values for the vars. 
$data = preg_replace($codes, $html, $data); 

da jedoch diese Saiten ständig ändern, kann es vorkommen, dass ein String wie dies erforderlich ist/eingefügt in eine der $ txt Array-Variablen:

$txt['dp_who_page'] = 'Viewing the page &quot;<a href="'.$scripturl.'?page=%1$s">%2$s</a>&quot; . '; 

Wo die Variable mit dem . und dem Ende der String-Variable hat diese . '; gerafft, die sich von dem unterscheidet, was es oben erwähnt wurde, was das war:

$txt['dp_who_page'] = 'Viewing the page &quot;<a href="' . $scripturl . '?page=%1$s">%2$s</a>&quot;.'; 

In jedem dieser Fälle, ich brauche es, um das obige $ txt ['dp_who_page'] wie folgt zurückzugeben:

Anzeigen des Forenindex von {context [forum_name]}.

Derzeit funktioniert es nicht richtig mit dem 2. Fall.

Wie kann ich dies mit dem folgenden preg_replace-Code oben für beide oben aufgeführten Fälle tun? Was muss geändert werden?

Ich verwende die PHP-Funktion eval(), um die Variablen zu extrahieren.

OK, hier ist die gesamte Funktion:

function loadLanguageFile($language, $file) { 

    $temp = array(); 

    $data = file_get_contents('./'.$language.'/'.$file.'.'.$language.'.php'); 

    $codes = array (
     '/(\' \. \$)(.+?)(\. \')/', 
     '/(\= \$)(.+?)(\. \')/', 
      '/(\' \. \$)(.+?)(\;)/', 
     '/(\[\')(.+?)(\'\])/', 
     '/<\?php/s', '/\?>/s', '/<\?/s' 
    ); 
    $html = array (
     '{$2}', 
     '= \'{$2}', 
     '{$2}\';', 
     '[$2]', 
     '', 
    ); 
    // Since we don't have the values for the vars. 
    $data = preg_replace($codes, $html, $data); 

    // We must change this because they are global. 
    $data = str_replace('$txt', '$langEditor_txt', $data); 
    $data = str_replace('$helptxt', '$langEditor_helptxt', $data); 

    eval($data); 

    if (isset($langEditor_txt)) { 
     $temp['txt'] = $langEditor_txt; 
     unset($GLOBALS['langEditor_txt']); 
    } 
    if (isset($langEditor_helptxt)) { 
     $temp['helptxt'] = $langEditor_helptxt; 
     unset($GLOBALS['langEditor_helptxt']); 
    } 

    return $temp; 
} 

Sie können hier gehen, um zu sehen, was ich, im Grunde zu erreichen versuchen, ich will Strings erlauben, auf Englisch übersetzt in den Sprachen zu erleichtern, wird basierend Zeichenfolgen dieser Sprachen: Language TEST using this function to load the language. Klicken Sie auf eine Sprache (derzeit nur Spanisch, Französisch, Englisch verfügbar), dann bearbeiten Sie die Sprache und Sie werden sehen, dass preg_replace wirksam wird. Wenn Sie die DreamPortal-Sprache bearbeiten, ist dies ein gutes Beispiel dafür, was sie tun soll. Auch die Standard-Textfeldfelder sind (nachdem Sie auf eine Sprache View Link geklickt haben, als klicken Sie auf den Create It Link) laden die englischen Zeichenfolgen aus den tatsächlichen englischen Dateien in allen Sprachen. Das preg_replace verwendet dies also, um diese spezifische Zeichenfolgendefinition in das Standardtext-Textfeld einzugeben.

+5

Ich denke, Sie müssen Ihre Implementierung komplett überdenken. – prodigitalson

+0

Kann mir bitte jemand helfen? Ich werde dieses preg_replace in mehreren Sprachen verwenden. Und muss die meisten, wenn nicht alle Sprachen unterstützen. Wenn die Strings bearbeitet werden müssen, damit es ein besseres System für i18n ist, lass es mich wissen, was wäre das Beste dafür? Danke :) – SoLoGHoST

+4

Es ist wirklich schwer zu verstehen, was deine Regexes erreichen sollen. Außerdem: Verwenden Sie doppelte Anführungszeichen, wenn Sie einige Escapes ersparen. Und wenn es nur zum Übersetzen von Strings ist, benutze die verdammten gettext-Funktionen und sprintf. – mario

Antwort

1

Ich verstehe nicht, warum Sie das tun, aber das unmittelbare Problem scheint diese hier-und-wieder-weg-Räume zu sein. Die unmittelbare Lösung wäre die Räume optional zu machen:

'/(\'\s*\.\s*\$)(.+?)(\s*\.\s*\')/', 
'/(=\s*\$)(.+?)(\s*\.\s*\')/', 
'/(\'\s*\.\s*\$)(.+?)(;)/', 
'/(\[\')(.+?)(\'\])/', 
'/<\?php/s', '/\?>/s', '/<\?/s' 

\s* entspricht null oder mehr Leerzeichen.

+0

Gibt es eine bessere Möglichkeit, all diese regulären Ausdrücke zu verkürzen? Ich bin offen für weitere Optionen. Danke, nebenbei, es funktioniert :) – SoLoGHoST

3

Ich empfehle, gettext() zu verwenden. Auf diese Weise können Sie gettext-Katalogdateien verwenden, die mit Werkzeugen wie Poedit (die auch translation memory verwendet) bearbeitet werden können.

+0

Ich verstehe nicht, wie man 'gettext()' verwendet, scheint, dass die Zeichenfolge an es übergeben wird, aber wie genau? – SoLoGHoST

+0

Sie rufen einfach die Funktion auf. wie '_ ('String, den ich übersetzen muss')' und vorausgesetzt, Sie haben diesen String der Übersetzungstabelle hinzugefügt, wird der übersetzte String zurückgegeben. Sie müssen das Gebietsschema einrichten und zuerst die Übersetzungstabelle binden. aber das ist alles in der gettext documentaion. Persönlich bin ich kein Fan von gettext, weil Sie ein binäres Format für die Übersetzungstabellen verwenden müssen, ich bevorzuge xliff selbst, was XML-basiert und somit für Menschen lesbar ist. Zend_Translate ist in dieser Hinsicht großartig, da es eine Reihe von Formaten unterstützt (einschließlich xliff und gettext), aber eine einzige Schnittstelle verwendet. – prodigitalson

+0

unterstützt es auch Position platziert Text Ersatz aus der Box ähnlich wie Sie versuchen zu tun. – prodigitalson

1

Wenn ich Sie wäre würde ich die nativen Funktionen wie bereits vorgeschlagen oder Zend_Translate oder eine andere i18n Bibliothek verwenden.

+0

+1 für [Zend_Translate] (http://framework.zend.com/manual/en/zend.translate.html) –