tami: SEPA konformen String erzeugen mit preg_replace

hi alle,

gemäß https://www.rb-wolfhagen.de/content/dam/f0083-0/download-dokumente/SEPA/Zeichensatz SEPA-Zahlungen.pdf sind bei SEPA im Verwendungszweck folgende Zeichen erlaubt:

a b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9
/ - ? : ( ) . , ‚
+
Space

Was das kleine Komma nach dem Komma in der vorletzten Zeile ist, weiß ich nicht.

Ich habe jetzt probiert:

$dirty = '#*~;_}][{&%$§!\\';  
$clean = 'a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 / - ? : ( ) . , ‚ + ';  
$dirtyAndClean = $dirty . $clean;  
$sepaClean = preg_replace("/[^a-zA-Z0-9\/\-?:()\.‚‚+ ]/si", "", $dirtyAndClean);  
var_dump($dirty);  
var_dump($clean);  
var_dump($sepaClean);

Ergebnis:

string(15) "#*~;_}][{&%$§!"
string(144) "a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 / - ? : ( ) . , ‚ + "
string(143) "a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 / - ? : ( ) .  ‚ + "

Nur das kleine Extrakomma fehlt. Weiß jemand warum? Habe es versucht einzubauen, aber "funzt" nicht. Ist vielleicht auch kein Drama, weil ich es vermutlich eh nicht benutze.

Sonst noch irgendwelche Tipps zum Vorgehen überhaupt?

mfg

tami

  1. Hi,

    Was das kleine Komma nach dem Komma in der vorletzten Zeile ist, weiß ich nicht.

    Guck mal hier. Ev ein SINGLE LOW-9 QUOTATION MARK

    /[^a-zA-Z0-9\/\-?:()\.,+ ]/si funktioniert bei mir.

    lG, Robert

    1. hi Jonny,

      Hi,

      Was das kleine Komma nach dem Komma in der vorletzten Zeile ist, weiß ich nicht.

      Guck mal hier. Ev ein SINGLE LOW-9 QUOTATION MARK

      /[^a-zA-Z0-9\/\-?:()\.,+ ]/si funktioniert bei mir.~~~php

        
      ~~~php
      var_dump(ord("‚"));  
      var_dump(ord(","));  
      
      

      Bringt mir:

      int(130)
      int(44)

      Ich denke, ich lasse das 130er einfach weg ...; ich hatte komischerweise zweimal nach 130 gecheckt in meinem Beispiel.

      mfg

      tami

  2. Hakuna matata!

    Sonst noch irgendwelche Tipps zum Vorgehen überhaupt?

    PHP hat seine Schwierigkeiten mit UTF8-Strings. Wenn du kannst, dann benutze besser mb_ereg_replace(), dafür ist auch viel besser dokumentiert, wie man die richtige Zeichenkodierung einstellt.

    --
    “All right, then, I'll go to hell.” – Huck Finn
    1. Tach!

      PHP hat seine Schwierigkeiten mit UTF8-Strings.

      Ja.

      Wenn du kannst, dann benutze besser mb_ereg_replace(), dafür ist auch viel besser dokumentiert, wie man die richtige Zeichenkodierung einstellt.

      Nein! ereg_... sind die POSIX-Funktionen. Die sind eigentlich deprecated. Es wundert mich, dass sie bei den MB-Strings noch erlaubt sind. Besser ist es, bei preg_... zu bleiben und da den Modifizierer u (kleines u, das große steht für was anderes) zu verwenden.

      Allerdings ist UTF-8 in dem vorliegenden Fall völlig irrelevant, weil die erlaubten Zeichen sowieso alle nur im ASCII-Bereich liegen.

      Wenn man mal ein anderes Dokument, eins von der Deutschen Bundesbank, nimmt, dann sieht man da übrigens keine zwei Kommas, sondern nur eins, dafür aber noch ein Hochkomma, das in dem anderen Dokument fehlt.

      dedlfix.

      1. hi dedlfix,

        Wenn man mal ein anderes Dokument, eins von der Deutschen Bundesbank, nimmt, dann sieht man da übrigens keine zwei Kommas, sondern nur eins, dafür aber noch ein Hochkomma, das in dem anderen Dokument fehlt.

        Das eine ist Ascii 44 (das normale Komma), das andere Ascii 130. S.a. http://www.petefreitag.com/cheatsheets/ascii-codes/. Ich hatte in meinem Beispiel oben 2x130 drin, warum auch immer. Ascii 130 kennichnicht. Muss auch nicht rein. Das Hochkomma habe ich mit reingenommen. Danke.

        Die Umlaute müssen natürlich vorher ersetzt werden:

        $deutscheSonderzeichen = array("ä","ö","ü","ß","Ä","Ö","Ü");  
        $deutscheSonderzeichenFürSepa   = array("ae", "oe", "ue", "ss", "Ae", "Oe", "Ue");  
          
        $dirty = 'üäöÜÖÄß#*~;_}][{&%$§!\\';  
        $clean = 'a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 \' : ? , - ( + . ) /';  
          
        $cleanAndDirty = $clean . $dirty;  
          
        $stillDirty  = str_replace($deutscheSonderzeichen, $deutscheSonderzeichenFürSepa, $cleanAndDirty);  
          
        $sepaNotAllowed = "/[^a-zA-Z0-9\/\-?:()\.',+ ]/si";  
        $notAllowedReplacement = "";  
        $sepaClean = preg_replace($sepaNotAllowed, $notAllowedReplacement, $stillDirty);  
          
          
        var_dump($dirty);  
        var_dump($clean);  
        var_dump($sepaClean);  
        
        

        gibt:

        string(22) "üäöÜÖÄß#*~;_}][{&%$§!"
        string(143) "a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ' : ? , - ( + . ) /"
        string(157) "a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ' : ? , - ( + . ) /ueaeoeUeOeAess"

        mfg

        tami

        1. Hi,

          Das eine ist Ascii 44 (das normale Komma), das andere Ascii 130.

          Gar nie niemals nicht. Denn ASCII kennt nur Zeichen bis zum Codepunkt 127.

          cu,
          Andreas

          --
          Warum nennt sich Andreas hier MudGuard?
          O o ostern ...
          Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.
          1. Gar nie niemals nicht. Denn ASCII kennt nur Zeichen bis zum Codepunkt 127.

            Gibt es da nicht das ANSI mit 217 Kotpunkten bzw ist das cp1252?

            Wie auch immer :) schönen Abend, Robert

            1. Hallo,

              217 Kotpunkten

              vielen dank, dass du mich an meine weihnachtliche Magendarmgrippe erinnerst :(

              Gruß
              Kalk

      2. Hakuna matata!

        Wenn du kannst, dann benutze besser mb_ereg_replace(), dafür ist auch viel besser dokumentiert, wie man die richtige Zeichenkodierung einstellt.

        Nein! ereg_... sind die POSIX-Funktionen. Die sind eigentlich deprecated. Es wundert mich, dass sie bei den MB-Strings noch erlaubt sind.

        Die ereg-Funktionen und die mb_ereg-Funktionen stammen aus verschiedenen Erweiterungen, ich sehe keinen Grund dafür, warum die mb_ereg-Funktionen in naheliegender Zukunft auch missbilligt werden sollten. In der Begründung heißt es zwar, dass die POSIX-Syntax für reguläre Ausdrücke zugunsten der Perl-Syntax aufgegeben worden sei, aber inzwischen sind PHPs preg-Funktionen auch schon lange nicht mehr Perl-kompatibel und werden sie vermutlich auch nicht mehr werden. Wenn das Argument nochmal angeführt werden sollte und die PHP-Macher sich auf einen Standard zurückbesinnen wollten, dann hätten die preg-Funktionen m.M.n. auch nur sehr schlechte Karten auf eine aussichtsreiche Zukunft.

        Besser ist es, bei preg_... zu bleiben und da den Modifizierer u (kleines u, das große steht für was anderes) zu verwenden.

        Ich bin mir mangels Dokumentation nicht sicher, aber ich nehme an, dass man in diesem Fall auch noch die interne Zeichenkodierung mit mb_internal_encoding() setzen müsste.

        Allerdings ist UTF-8 in dem vorliegenden Fall völlig irrelevant, weil die erlaubten Zeichen sowieso alle nur im ASCII-Bereich liegen.

        Wirklich? Ich kann in der ASCII-Tabelle keine Entsprechung zum SINGLE LOW-9 QUOTATION MARK, welches Jonny 5 hier identifziert hat, entdecken. Aber auch wenn, dann bedeutet das ja noch nicht, dass die zu untersuchende Zeichenkette auch im ASCII-Wertebereich liegt.

        --
        “All right, then, I'll go to hell.” – Huck Finn
        1. hi 1UnitedPower,

          Wirklich? Ich kann in der ASCII-Tabelle keine Entsprechung zum SINGLE LOW-9 QUOTATION MARK, welches Jonny 5 hier identifziert hat, entdecken. Aber auch wenn, dann bedeutet das ja noch nicht, dass die zu untersuchende Zeichenkette auch im ASCII-Wertebereich liegt.

          ord() gibt 130 dafür aus ...;

          mfg

          tami

          1. Hallo,

            Wirklich? Ich kann in der ASCII-Tabelle keine Entsprechung [...]
            ord() gibt 130 dafür aus ...;

            also ganz klar nicht ASCII, wie MudGuard schon bemerkte.

            Ciao,
             Martin

            --
            Chef zum Bewerber: Es gibt zwei Dinge, auf die ich allergrößten Wert lege. Das eine ist Sauberkeit! Haben Sie übrigens die Schuhe auf der Matte abgetreten? - Ja, selbstverständlich. - Gut. Das andere ist uneingeschränkte Ehrlichkeit. Übrigens, draußen liegt gar keine Fußmatte.
            Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
        2. Tach!

          Die ereg-Funktionen und die mb_ereg-Funktionen stammen aus verschiedenen Erweiterungen, ich sehe keinen Grund dafür, warum die mb_ereg-Funktionen in naheliegender Zukunft auch missbilligt werden sollten. In der Begründung heißt es zwar, dass die POSIX-Syntax für reguläre Ausdrücke zugunsten der Perl-Syntax aufgegeben worden sei, aber inzwischen sind PHPs preg-Funktionen auch schon lange nicht mehr Perl-kompatibel und werden sie vermutlich auch nicht mehr werden. Wenn das Argument nochmal angeführt werden sollte und die PHP-Macher sich auf einen Standard zurückbesinnen wollten, dann hätten die preg-Funktionen m.M.n. auch nur sehr schlechte Karten auf eine aussichtsreiche Zukunft.

          Es geht auch darum, keine zwei verschiedene Regexp-Syntaxen zu verwenden. Die pregs sind mächtiger als die eregs. Und da pregs mit UTF-8 umgehen können, sehe ich keinen Grund, die mb_eregs zu verwenden.

          Besser ist es, bei preg_... zu bleiben und da den Modifizierer u (kleines u, das große steht für was anderes) zu verwenden.
          Ich bin mir mangels Dokumentation nicht sicher, aber ich nehme an, dass man in diesem Fall auch noch die interne Zeichenkodierung mit mb_internal_encoding() setzen müsste.

          Nein, mbstrings und preg sind zwei verschiedene Erweiterungen. mb_irgendwas wirkt nur auf mb_irgendwasanderes. Der preg-Modifizierer u ist davon nicht beeinflusst.

          Allerdings ist UTF-8 in dem vorliegenden Fall völlig irrelevant, weil die erlaubten Zeichen sowieso alle nur im ASCII-Bereich liegen.
          Wirklich? Ich kann in der ASCII-Tabelle keine Entsprechung zum SINGLE LOW-9 QUOTATION MARK, welches Jonny 5 hier identifziert hat, entdecken.

          Ich kann im SEPA-Zeichensatz kein SINGLE LOW-9 QUOTATION MARK finden. weil ich davon ausgehe, dass das von tami verwendete Dokument fehlerhaft ist und das von der Bundesbank mehr Glaubwürdigkeit hat. Es wäre auch ziemlich verwechslungsträchtig, zwei gleich aussehende Zeichen zuzulassen. Und zum anderen, warum sollte von einem Anführungszeichen-Paar nur eins verwendet werden?

          Aber auch wenn, dann bedeutet das ja noch nicht, dass die zu untersuchende Zeichenkette auch im ASCII-Wertebereich liegt.

          Alle erlaubten Zeichen liegen im ASCII-Bereich. Alles was mit Bytes > 0x7F kodiert wird, ist sowieso nicht nicht erlaubt und fliegt raus. Es gibt keine unerlaubten Zeichen, die mit Bytes erlaubter Zeichen kodiert werden. Damit ist alles unerlaubte auch bei ASCII-Filterung problemlos rausgefiltert.

          dedlfix.

          1. Hakuna matata!

            Wenn das Argument nochmal angeführt werden sollte und die PHP-Macher sich auf einen Standard zurückbesinnen wollten, dann hätten die preg-Funktionen m.M.n. auch nur sehr schlechte Karten auf eine aussichtsreiche Zukunft.

            Es geht auch darum, keine zwei verschiedene Regexp-Syntaxen zu verwenden. Die pregs sind mächtiger als die eregs. Und da pregs mit UTF-8 umgehen können, sehe ich keinen Grund, die mb_eregs zu verwenden.

            Inwiefern mächtiger? Perls reguläre Ausdrücke sind in der Tat mächtiger, weil sie über die regulären Sprachen hinaus auch kontextfreie Sprachen entscheiden können (dank rekursiven Definitionen). PHPs "perl" regelar expressions können das allerdings nicht und sind damit auch nicht mächtiger als die regulären Ausdrücke aus dem POSIX Standard.

            Für die mb_eregs spricht, dass es sich dabei wirklich um standkonforme Sytanx handelt und nicht um eine weitere selbstgestrickte Syntax, die sich als perl-konform verkauft. Dagegen spricht, dass sie in der PHP-Community offensichtlich weniger beliebt sind.

            Nein, mbstrings und preg sind zwei verschiedene Erweiterungen. mb_irgendwas wirkt nur auf mb_irgendwasanderes. Der preg-Modifizierer u ist davon nicht beeinflusst.

            Asche über mein Haupt, das kann man sogar an der Stelle der Dokumentation nachlesen, die ich selber verlinkt habe.

            Allerdings ist UTF-8 in dem vorliegenden Fall völlig irrelevant, weil die erlaubten Zeichen sowieso alle nur im ASCII-Bereich liegen.
            Wirklich? Ich kann in der ASCII-Tabelle keine Entsprechung zum SINGLE LOW-9 QUOTATION MARK, welches Jonny 5 hier identifziert hat, entdecken.

            Ich kann im SEPA-Zeichensatz kein SINGLE LOW-9 QUOTATION MARK finden. weil ich davon ausgehe, dass das von tami verwendete Dokument fehlerhaft ist und das von der Bundesbank mehr Glaubwürdigkeit hat.

            Achso, das ergibt Sinn ja.

            Aber auch wenn, dann bedeutet das ja noch nicht, dass die zu untersuchende Zeichenkette auch im ASCII-Wertebereich liegt.

            Alle erlaubten Zeichen liegen im ASCII-Bereich. Alles was mit Bytes > 0x7F kodiert wird, ist sowieso nicht nicht erlaubt und fliegt raus. Es gibt keine unerlaubten Zeichen, die mit Bytes erlaubter Zeichen kodiert werden. Damit ist alles unerlaubte auch bei ASCII-Filterung problemlos rausgefiltert.

            Stimmt, ich hatte nicht bedacht, dass Bytes, wenn sie Teil eine Multybyte-Sequenz sind, stets einen höheren Wert haben als 0x7F, weil das erste Bit stets eine 1 sein muss. Vermutlich aus genau diesem Grund.

            --
            “All right, then, I'll go to hell.” – Huck Finn
            1. Tach!

              Es geht auch darum, keine zwei verschiedene Regexp-Syntaxen zu verwenden. Die pregs sind mächtiger als die eregs.
              Inwiefern mächtiger?

              Der Sprachumfang ist deutlich größer. Vergleiche PCRE und POSIX Regex (ja, das PHP-Handbuch verweist nur auf diese man page).

              dedlfix.

              1. Hakuna matata!

                Es geht auch darum, keine zwei verschiedene Regexp-Syntaxen zu verwenden. Die pregs sind mächtiger als die eregs.
                Inwiefern mächtiger?

                Der Sprachumfang ist deutlich größer. Vergleiche PCRE und POSIX Regex (ja, das PHP-Handbuch verweist nur auf diese man page).

                Oha, doch so gravierende Unterschiede. Du hast mich überzeugt, die Featurelist der PCRE-Ausdrücke spricht Bände: Look-Arounds, Non-capturing Subpatterns, Kommentare, bedingte Subpatterns und sogar rekursive Definitionen (entgegen meiner Annahme von vorhin). Dagegen hat POSIX nur die eher unnützen Äquivalenzklassen entgegen zu setzen. Damit schließe ich mich dir dann doch an, man sollte wirklich lieber zu den preg-Funktionen greifen. Gut nochmal darüber gesprochen zu haben.

                --
                “All right, then, I'll go to hell.” – Huck Finn
            2. @@1UnitedPower:

              nuqneH

              Perls reguläre Ausdrücke sind in der Tat mächtiger, weil sie über die regulären Sprachen hinaus auch kontextfreie Sprachen entscheiden können (dank rekursiven Definitionen).

              Weshalb die Ausdrücke ja nicht regulär sind und man sie auch nicht so nennen sollte.

              Qapla'

              --
              „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)