Ankündigung

Einklappen
Keine Ankündigung bisher.

Zeichenkette Erkennen, Zerlegen und Zusammensetzten

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Zeichenkette Erkennen, Zerlegen und Zusammensetzten

    Hi!
    Ich möchte versch. Barcodes scannen. Die Codes sind im Aufbau ähnlich.
    Ein Script soll nach dem Absenden eines Formulars die Zeichenkette zerlegen und wieder neu Zusammensetzten.
    Die Zeichenketten haben eine Unterschiedliche länge und können sowohl Ziffern, als auch Buchstaben enthalten. Die ersten 10 und die letzten 8 Zeichen sind jedoch immer Ziffern. Und genau die möchte ich erkennen und neu Zusammensetzten.

    Beispiel:
    Zeichenkette aus Barcode: 7806458236241212WH00000101
    gewünschtes Ergebnis: 7806.458.236_00000101

    Wichtig hier sind die Punkte und der Unterstrich als Trennzeichen.

    Wer kann hier helfen?

  • #2
    Die Funktion substr() sollte dir da weiterhelfen.
    http://php.net/manual/de/function.substr.php

    Kommentar


    • #3
      Alternativ mit preg_match prüfen und zerlegen. Ist gegenüber den Stringfunktionen nur zu empfehlen, wenn du fit bist mit Regulären Ausdrücken.

      Kommentar


      • #4
        Danke für die Info's!

        Hab's nun mal so gelöst:

        PHP-Code:
        $ident "7806988414121212WHJW00000123";
        $id substr($ident04).'.'.substr($ident43).'.'.substr($ident73).'_'.substr($ident, -8);  
        echo 
        $id
        Mit preg_match habe ich schonmal gearbeitet.
        Hab auch schon die Validierung des fertigen Strings:

        Code:
        @^[0-9]{4}\.[0-9]{3}\.[0-9]{3}_[0-9]{8}$@
        Nun wäre intersant, bei der Formular-Validierung zuerst den "rohen" String zu überprüfen. In Etwa (HTML5):

        pattern=[Anfang 10 Zahlen MUSS][Ende 8 Zahlen MUSS]

        Bei erfolgreicher Validierung erfolgt die Umwandlung.

        Kommentar


        • #5
          pattern=[Anfang 10 Zahlen MUSS][Ende 8 Zahlen MUSS]
          Code:
          ^     ist Anfang
          [0-9] oder [\d] ist eine Ziffer (0-9) und {10} danach heißt genau 10 mal
          .*    wäre ein beliebiges Zeichen beliebig oft (auch kein mal)
          [0-9] oder [\d] ist eine Ziffer (0-9) und {8} danach heißt genau 8 mal
          $     ist Ende
          
          Somit zB:
          ^[\d]{10}.*[\d]{8}$
          Wobei man das "in der Mitte" bestimmt auch noch eingrenzen kann, oder?
          The string "()()" is not palindrom but the String "())(" is.

          Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
          PHP.de Wissenssammlung | Kein Support per PN

          Kommentar


          • #6
            Um den rohen String zu prüfen halte ich es für sinnvoll auch festzulegen, was zwischen den Zahlenkolonnen stehen kann. Im Beispiel "241212WH". Also Ziffern, Großbuchstaben, ..? und die maximale Anzahl.
            Dann habe ich mit preg_match die Prüfung der Rohdaten und im match bei Erfolg gleich meine substrings für die Umwandlung. Die funktioniert dann zu 100% und ich muß dies nicht nochmal prüfen.

            Kommentar


            • #7
              Mist, zu langsam! Das Folgende hätte eigentlich vor #post833704 stehen sollen, aber ich habe zu oft drin rumeditiert und Erklärungen ergänzt. Egal, ein paar zusätzliche Informationen stehen ja drin.

              Zitat von Schmakus Beitrag anzeigen
              Hi!
              Die Zeichenketten haben eine Unterschiedliche länge und können sowohl Ziffern, als auch Buchstaben enthalten. Die ersten 10 und die letzten 8 Zeichen sind jedoch immer Ziffern. Und genau die möchte ich erkennen und neu Zusammensetzten.

              Beispiel:
              Zeichenkette aus Barcode: 7806458236241212WH00000101
              gewünschtes Ergebnis: 7806.458.236_00000101

              Wichtig hier sind die Punkte und der Unterstrich als Trennzeichen.

              Wer kann hier helfen?
              Unter Umständen könnte hier substr() reichen. Nur erkennt das keine fehlerhaften Eingaben, sondern schnippelt stur die vorgegebene Anzahl von Bytes am Anfang oder Ende gezählt ab.

              PHP-Code:
              substr($input010);
              substr($input, -8); 
              Mit preg_match() bekommst du eine Rückmeldung, falls die Eingabe fehlerhaft ist (was ja durchaus manchmal vorkommen soll):

              PHP-Code:
              preg_match('/\A([0-9]{10}).+?([0-9]{8})\z/'$input$h);
              var_dump($h); 
              Verwendet wird einfaches Pattern-Matching:
              \A finde am Anfang (niemals später)
              [0-9] eine Zeichenklasse mit den Ziffern 0...9
              {10} und das genau 10 mal
              . ein beliebiges Zeichen
              + beliebig oft (aber mindestens einmal)
              ? und bitte nicht weiter suchen, als bis wir das folgende Muster gefunden haben
              [0-9]{8} wie am Anfang, aber bitte etwas kürzer
              \z das Ganze muss bis zum Ende reichen (nicht vorher)

              ... und neu Zusammensetzten.
              Je nachdem, welchen Aufwand du betreiben möchtest, reicht ein preg_replace_callback() mit benutzerdefinierter Funktion, die ersetzt und formatiert:

              PHP-Code:
              $repl preg_replace_callback(
                  
              '/\A([0-9]{10}).+?([0-9]{8})\z/',
                  function (
              $h) {
                      return 
              preg_replace('/(?<=...)(?=(...)+\z)/''.'$h[1])
                          . 
              '_'
                          
              $h[2];
                  },
                  
              $input
              ); 
              Nachteil: Bei ungültigen Eingaben bekommt man den übergebenen String unverändert zurück.

              Man kann aber auch alles schön einzeln abarbeiten. Zuerst die Mustersuche:
              PHP-Code:
              function find_pattern($input) {
                  return 
              preg_match('/\A([0-9]{10}).+?([0-9]{8})\z/'$input$h)
                      ? 
              array_slice($h1)
                      : 
              null// eingabe fehlerhaft
              }

              $found find_pattern('7806458236241212WH00000101');
              var_dump($fp);
              // array(2) {
              //     [0] => string(10) "7806458236"
              //     [1] => string(8) "00000101"
              // } 
              Anschließend die Formatierung:
              PHP-Code:
              function format_numeric_string($numeric_string) {
                  return 
              preg_replace('/(?<=...)(?=(...)+\z)/''.'$numeric_string);
              }

              $found find_pattern('7806458236241212WH00000101');
              $fmt format_numeric_string($found[0]);
              var_dump($fmt);
              // string(12) "7806.458.236" 
              ... und schließlich beides zusammenkleben:

              PHP-Code:
              // ...
              var_dump(format_numeric_string($fp[0]) . '_' $fp[1]);
              // string(21) "7806.458.236_00000101" 
              Stellt sich nur noch die Frage, wie du die Formatierung des ersten Ziffernblocks exakt haben willst. Vielleicht könnte man auch die in PHP eingebaute Funktion number_format() verwenden.

              Meine Variante mit preg_replace() macht folgendes:
              suche einen Zeichenzwischenraum (quasi: nichts)
              (?<=...) vor dem mindestens 3 Zeichen stehen
              und
              (?=(...)+\z) nach dem mindestens exakt 3, 6, 9, ... Zeichen stehen, bevor der String endet
              und füge dort einen Punkt ein

              Siehe auch (für den Einstieg): http://de.wikipedia.org/wiki/Regulär..._in_der_Praxis


              Zitat von Schmakus Beitrag anzeigen

              Nun wäre intersant, bei der Formular-Validierung zuerst den "rohen" String zu überprüfen. In Etwa (HTML5): ...
              Die Regulären Ausdrücke, die JavaScript (ECMA-Script) verarbeiten kann, unterscheiden sich nicht wesentlich von denen, die PHP verwendet (PCRE). Aber es schadet nicht, sie genauer zu kennen:
              https://developer.mozilla.org/en-US/...ar_Expressions

              pattern=[Anfang 10 Zahlen MUSS][Ende 8 Zahlen MUSS]
              HTML-Code:
              <input pattern="\A([0-9]{10}).+?([0-9]{8})\z" .../>
              Bei erfolgreicher Validierung erfolgt die Umwandlung.
              Bei erfolgreicher Validierung erlaubt ein aktueller Browser seinem Bediener, das Formular an dein Serverscript zu senden. Alle anderen Clients machen das ohne diesen Test. Deswegen musst du auf dem Server unbedingt nochmal diesen Check machen.
              Wenn man die Wurst schräg anschneidet, hält sie länger, weil die Scheiben größer sind.

              Kommentar


              • #8
                WOW! @fireweasel: Das ist mal eine ausführliche Erklärung! Vielen Dank!
                Werde das gleich mal ausprobieren!

                Kommentar


                • #9
                  @fireweasel: Dein Code funktioniert leider nicht richtig. Die Variablen $fp und $input sind nicht definiert.
                  Leider weiß ich selber nicht, was ich ersetzten soll.
                  Bitte um Hilfe!

                  Kommentar


                  • #10
                    PHP-Code:
                    $found find_pattern('7806458236241212WH00000101'); 
                    var_dump($fp); 
                    // array(2) { 
                    //     [0] => string(10) "7806458236" 
                    //     [1] => string(8) "00000101" 
                    // } 
                    $fp sollte wohl $found heissen und $input ist dein Eingangswert... Zeig sonst mal genau was du dir von oben alles zusammenkopiert hast
                    The string "()()" is not palindrom but the String "())(" is.

                    Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
                    PHP.de Wissenssammlung | Kein Support per PN

                    Kommentar


                    • #11
                      Hi,
                      ich habe nun das erste Beispiel in Verwendung.

                      PHP-Code:
                      preg_match('/\\A([7]{1}[8]{1}[0-9]{2}[.]?[0-9]{3}[.]?[0-9]{3}).*?([0-9]{8})\\z/'$Input$h);
                          
                          
                      $Ident preg_replace_callback(
                          
                      '/\\A([7]{1}[8]{1}[0-9]{2}[.]?[0-9]{3}[.]?[0-9]{3}).*?([0-9]{8})\\z/',
                          function (
                      $h) {
                              return 
                      preg_replace('/(?<=...)(?=(...)+\z)/''.'$h[1])
                                  . 
                      '_'
                                  
                      $h[2];
                          },
                          
                      $Input
                          
                      ); 
                      Das funktioniert soweit ganz gut, solange der Input keine Punkte enthält.
                      Das Preg-Match lässt folgendes zu:
                      • 7833.444.555_87654321
                      • 783344455587654321
                      • 7833444555XYZ87654321
                      • usw.

                      In meine Datenbank soll aber IMMER nur die folgende Form eingefügt werden:
                      7833.444.555_87654321

                      Wie muss ich das Script verändern?

                      Kommentar


                      • #12
                        Ich hab folgenden Code voran gesetzt. Ist das konform?

                        PHP-Code:
                        $Ident  preg_replace("/[^0-9a-zA-Z]/" '' $Ident); 

                        Kommentar

                        Lädt...
                        X