Tobias Kloth: Komplizierte Textdatei in MySQL umwandeln

Beitrag lesen

Hallo Ralf,

Am Zeilenbeginn steht ein dt. Ausdruck, dann ein Trennzeichen und  kein bis mehrere engl. Ausdruck, die mit (E) beginnen, dann min. ein jap Ausdruck, der mit (J) beginnt, alles immer mit dem "|" getrennt:
aaaaa|(E)bbbbb|(E)ccccc|(J)xxxxx|(J)yyyyy

du hast Glück - das hat mich interessiert, ob das mit einem regulären Ausdruck zu lösen ist :-)
Nach einigem Probieren habe ich dann eine Lösung gefunden, allerdings musste das was der reguläre Ausdruck ausspuckt erst noch weiterverarbeitet werden, um die einzelnen Wörter zu erhalten:

/*
  Funktion: sucheSprachen
  Parameter: string - der zu zerteilende String
             sprachen - ein Array mit den Sprachen in der Form:
                 <Kürzel zwischen den Klammern> => '<sprachkürzel>'
                z.B. also: array('E'=>'en','J'=>'jp')
                die Sprachen müssen allerdings in der Reihenfolge angegeben werden wie
                sie auch im String vorkommen, sonst wird nur die letzte Sprache gefunden
  Rückgabe: ein Array mit:
    - dem deutschen String ($rueckgabe['de'])
    - je einem Array mit der enthaltenen Sprache (im Beispiel: $rueckgabe['en'] u. $rueckgabe['jp'])
*/
function sucheSprachen($string,$sprachen){
  //evtl. vorhandene Leerzeichen und Zeilenumbrüche entfernen
  $string = trim($string);
  //Beginn des regulären Ausdrucks (s.u.)
  $regexpr = '~(.*?)|';
  //das Array $sprachen wird durchlaufen und für jedes Kürzel wird der reguläre Ausdruck ergänzt
  foreach($sprachen as $klammer => $kuerzel){  //->http://www.php.net/foreach
    $regexpr .= '((?:('.$klammer.')[^|]*[|]?)+)?';
  }
  //Ende des regulären Ausdrucks
  $regexpr .= '~';
  /*
  wenn die Funktion mit array('E'=>'en','J'=>'jp') aufgerufen wird, sieht der
  generierte reguläre Ausdruck dann so aus:
    ~^(.*?)|((?:(E)[^|]*[|]?)+)?((?:(J)[^|]*[|]?)+)?$~
  damit er etwas übersichtlicher wird (und zum Erklären), habe ich mal ein
   paar Zeilenumbrüche eingebaut:

~^  # Beginn des regulären Ausdrucks mit Anker für den Beginn des Strings
  (.*?)|  #findet den deutschen Ausdruck mit einem | dahinter
  (          # Beginn der Speicherung der englischen Ausdrücke
    (?:      # mit der Klammer werden die einzelnen Wörter gefunden, das '?:' ist dafür da,
             #  dass das der Treffer nicht gespeichert wird
       (E) # findet das '(E)'
       [^|]* # findet alle Zeichen außer | (was ja das Ende des Wortes markiert)
       [|]?  # findet das | (optional weil am Ende des Strings kein | mehr steht)
    )+       # Ende des Bereiches für die einzelnen Wörter, muss mindesten einmal gefunden werden
  )?         # Ende der Speicherung der englischen Ausdrücke (optional, um Fehler zu vermeiden,
             #  wenn in $sprachen eine Sprache angegeben ist, die in $string nicht vorkommt)
  ((?:(J)[^|]*[|]?)+)?  # das gleiche wie für die englischen Teile
  $~  # Ende des regulären Ausdrucks mit Anker für den Ende des Strings
  */
  //wendet den regulären Ausdruck auf $string an, und speichert die Treffer in $match
  preg_match($regexpr,$string,$match);  //->http://de3.php.net/preg_match
  //speichert den deutschen Treffer im Rückgabearray
  $ergebnis['de'] = $match[1];
  //löscht die ersten zwei Elemente von $match (der gesamte String, und der deutsche Treffer)
  unset($match[0]);
  unset($match[1]);
  foreach($match as $sprache){
    //sucht sich das Kürzel, dass in den Klammern steht
    $temp = substr($sprache,1,1);  //->http://de3.php.net/substr
    //speichert den Sprachenstring zusammen mit mit dem Kürzel als Key in $match2
    $match2[$temp] = $sprache;
  }
  foreach($match2 as $sprache => $woerter){
    //löscht evtl. vorhandene | aus dem "Sprachenstring" und auch gleich das führende '(E)'
    $woerter = str_replace('|','',substr($woerter,strlen($sprache)+2));
    //teilt das ganze an '(E)' (bzw. '(J)') auf und speichert das ganze im Rückgabearray
    $ergebnis[$sprachen[$sprache]] = explode('('.$sprache.')',$woerter);
  }
  //und das Ergebnis noch zurückgeben
  return $ergebnis;
}

das ganze mit den Parametern:
  $zeile = 'aaaaa|(E)bbbbb|(E)ccccc|(J)xxxxx|(J)yyyyy';
  $sprachen = array('E'=>'en','J'=>'jp');
und dem funktionsaufruf:
$ergebnis = sucheSprachen($zeile,$sprachen);
aufgerufen, gibt dann mit
  print_r($ergebnis);
dieses Ergebnis:

Array
(
  [de] => aaaaa
  [en] => Array
    (
      [0] => bbbbb
      [1] => ccccc
    )
  [jp] => Array
    (
      [0] => xxxxx
      [1] => yyyyy
    )
)

  • alle Klarheiten beseitigt? :-)

Bei Fragen, Fehlern o.ä. einfach nochmal posten

Grüße aus Nürnberg
To*bittenichtschlagenweilicheinevollständigelösunggepostethabe*bias

--
Selfcode: sh:( fo:) ch:? rl:( br:< n4:& ie:% mo:| va:) de:] zu:) fl:( ss:| ls:[ js:|