1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

RegEx: String A im String B ersetzen mit modifiziertem String A

Dieses Thema im Forum "Sonstige Sprachen" wurde erstellt von N0ACE, 22. August 2013.

  1. N0ACE

    N0ACE Mitglied

    Hallo liebe Community,

    ich habe folgende Situation: Ein String:
    Code (Text):
    1. Das Modell AB0FF2DE23 ist in Reparatur
    Dabei soll das Modell ("AB0FF2D23") umgewandelt werden. Die Modell-Nr. besteht immer aus drei Blöcken, welche unterschiedlich aufgebaut sein können.

    Ziel ist es, den String so umzuwandeln, dass er wie folgt erscheint:
    Code (Text):
    1. Das Modell AB0 FF2 DE23 ist in Reparatur
    Das RegEx-Pattern, welches das Modell ("AB0FF2D23") herausfiltert ist vorhanden (die drei Blöcke können unterschiedlich aufgebaut sein):
    Code (Text):
    1. ([A-Z]{2}\d|\d{3})([A-Z]{2}\d{1,2}|\d{3}|[A-Z]{3})(_)?([A-Z]\d{3}|[A-Z]{1,3}\d{2}|[A-Z]{3}\d|[A-Z]{4}|\d{3})(_2)?
    Wie erreiche ich es, dass o.g. Satz so umgewandelt wird, dass zwischen den drei Blöcken je ein Leerzeichen eingesetzt wird ("AB0 FF2 DE23") und damit das orig. Modell ersetze?


    Vielen Dank für Eure Hilfe und weiterhin einen schönen Tag!!

    Nachtrag:

    Ich arbeite in PHP und meine bisherigen Ansätze beziehen sich auf eine Kombination von preg_match() um die Modell-Nr. herauzufiltern und via implode() "schön" zu machen und diese dann via preg_replace() im Ursprungs-String zu ersetzen.

    Gibt es hier eine elegantere, performantere Möglichkeit?
     
  2. deepthroat

    deepthroat Erfahrenes Mitglied

    Hi.

    Was soll den mit den _ und _2 Teilen passieren?

    Grundsätzlich kannst du natürlich versuchen mit einem preg_replace auszukommen, falls du die _ und _2 weglassen willst?

    Code (PHP):
    1. preg_replace('/([A-Z]{2}\d|\d{3})([A-Z]{2}\d{1,2}|\d{3}|[A-Z]{3})(_)?([A-Z]\d{3}|[A-Z]{1,3}\d{2}|[A-Z]{3}\d|[A-Z]{4}|\d{3})(_2)?/', '\1 \2 \4', $text);
    Test: http://www.myregextester.com/?r=de2e1e69
     
  3. N0ACE

    N0ACE Mitglied

    Der "_" zwischen Block 2 und 3 und das "_2" am Ende sind optional und tauchen (leiden) in manchen Modell-Nr. auf und sind daher notwendig. Sollte eines der beiden gefunden werden, soll da aber KEINE Leerzeichen zwischen.

    Bsp:
    Code (Text):
    1. AB0FF2_DE23_2
    Soll zu:
    Code (Text):
    1.  AB0 FF2_DE23_2
    Ist ein wenig fickerig, aber leider Voraussetzung ...


    Danke für die Hilfe!

    Dein Ansatz gefällt mir sehr gut! Wie gesagt, sind "_" und "_2" notwendig.

    Gibt es eine Möglichkeit, das Leerzeichen zwischen Block 2 und 3 nur dann zu setzen, wenn KEIN "_" gefunden wurde?

    Hier mein Bsp.: http://www.myregextester.com/?r=2fac15c6
     
  4. Yaslaw

    Yaslaw n/a Moderator

    Alle Nummern finden die nicht an eine Zahl oder einen Buchstaben grenzen (dank den Assertions am Anfang und am Ende des Pattern)

    Code (Text):
    1. == Findet Die Nummer ==
    2. Das Modell AB0FF2DE23 ist in Reparatur
    3. Das Modell AB0FF2DE23
    4. Das Modell AB0FF2DE23.
    5. Das Modell "AB0FF2DE23"
    6. Das Modell (AB0_FF2 DE23)
    7.  
    8. ==Findet Nicht
    9. Das ModellAB0FF2DE23
    10. Das Modell AB0FF2DE23123
    Code (PHP):
    1. $pattern = '/(?<![[:alnum:]])([[:alpha:]]{2}\d)[ ]?([[:alpha:]]{2}\d)[ ]?([[:alpha:]]{2}\d{2})(?![[:alnum:]])/';
    2. $replace = '\1 \2 \3';
    3. $result = preg_replace($pattern, $replace, $subject);
    Und falls es anstelle von Leerzeichen _ haben kann
    Code (PHP):
    1. $pattern = '/(?<![[:alnum:]])([[:alpha:]]{2}\d)[ _]?([[:alpha:]]{2}\d)[ _]?([[:alpha:]]{2}\d{2})(?![[:alnum:]])/';
     
  5. deepthroat

    deepthroat Erfahrenes Mitglied

    Nein, das geht lieder nicht mit preg_replace. Den zweiten Fall kann man noch als Spezialfall behandeln indem man das _2 einfach in die Gruppe hineinzieht:
    Code (Text):
    1. ([A-Z]{2}\d|\d{3})([A-Z]{2}\d{1,2}|\d{3}|[A-Z]{3})(_?)((:?[A-Z]\d{3}|[A-Z]{1,3}\d{2}|[A-Z]{3}\d|[A-Z]{4}|\d{3})(:?_2)?)
    Aber beim _ funktioniert das Leider nicht. Du kannst stattdessen preg_replace_callback Funktion verwenden oder mußt mehrfach ersetzen: 1. Fall ohne _ und mit Leerzeichen, 2. Fall mit _ und ohne Leerzeichen.

    Code (PHP):
    1. function format_model($matches) {
    2.   $delim = ($matches[3]) ? $matches[3] : ' ';
    3.  
    4.   return $matches[1] . ' ' . $matches[2] . $delim . $matches[4];
    5. }
    6.  
    7. preg_replace_callback('/([A-Z]{2}\d|\d{3})([A-Z]{2}\d{1,2}|\d{3}|[A-Z]{3})(_?)((:?[A-Z]\d{3}|[A-Z]{1,3}\d{2}|[A-Z]{3}\d|[A-Z]{4}|\d{3})(:?_2)?)/'',
    8.  'format_model',
    9.  '...');
    (ungetestet)
     
    Zuletzt bearbeitet: 22. August 2013
  6. N0ACE

    N0ACE Mitglied

    Vielen Dank für die rasche, zahlreiche und sehr gute Hilfe!

    Nach Absprache werden wir so verbleiben, dass wir den Underscore zwischen Block 2 und 3 nicht darstellen werden, sodass wir mit folgender Lösung äußerst zufrieden sind: http://www.myregextester.com/?r=c5e7f0c0

    Nochmals vielen Dank******
     
Die Seite wird geladen...