Enrico: Meldung "No ending delimiter '/' found" bei Entfernen Backslah

Hallo und Mahlzeit,

ich möchte mehrfach hintereinander vorkommende Satzzeichen durch jeweils nur ein Satzzeichen ersetzen, d.h., aus beispielsweise "!!!!" soll "!" werden:

$Inhalt = "Ein    beliebiger  Text       !!!?????";

$Zeichen = array (' ', '!', '?');

for ($i = 0; $i < count ($Zeichen); $i++)
   {
      $Inhalt = preg_replace ('/' . $Zeichen [$i]. '+/', $Zeichen [$i], $Inhalt);
   }

Ich habe das Array bewusst noch so klein gehalten, da ich es Satzzeichen für Satzzeichen erweitern möchte, da es ja Zeichen gibt (meines Wissens nach "\ ^ . $ | ( ) [ ] * + ? { } ,"), die maskiert werden müssen und ich möchte hier nicht gleich die fehlerhafte Nadel im Heuhaufen suchen müssen.

Obiger Code funktioniert einwandfrei, lediglich habe ich bei den maskierten Zeichen, hier "?", das Problem, dass der Backslash natürlich auch mit ausgegeben wird.

In meinem Code wird damit aus...

Ein    beliebiger  Text       !!!?????

die neue Zeichenkette...

Ein beliebiger Text !?

Ich habe daraufhin versucht, den Backslash zu entfernen:

$Inhalt = preg_replace ('//', '', $Inhalt);

Hier bekam ich aber die Fehlermeldung "No ending delimiter '/' found".

Gut, daraufhin habe ich den Backslah maskiert:

$Inhalt = preg_replace ('/\/', '', $Inhalt);

Aber leider immer noch mit der Fehlermeldung als Resultat.

Wo liegt mein Fehler bzw. gibt es für mein Vorhaben vielleicht noch eine bessere Variante, die ihr empfehlen würdet?

Vielen Dank und Gruß,
Enrico

  1. Hallo Enrico,

    Obiger Code funktioniert einwandfrei, lediglich habe ich bei den maskierten Zeichen, hier "?", das Problem, dass der Backslash natürlich auch mit ausgegeben wird.

    In meinem Code wird damit aus...

    Ein    beliebiger  Text       !!!?????

    die neue Zeichenkette...

    Ein beliebiger Text !?

    beim zweiten Parameter von preg_replace brauchst Du die Maskierung nicht. Wenn Du die da weglässt, sollte es funktionieren.

    Gruß, Dennis

    1. Hallo Dennis,

      erstmal danke für Deine rasche Antwort.

      beim zweiten Parameter von preg_replace brauchst Du die Maskierung nicht.

      Meinst Du damit die Angabe, mit der ein Suchmuster ersetzt werden soll?

      $Inhalt = preg_replace ('/' . $Zeichen [$i]. '+/', $Zeichen [$i], $Inhalt);
                                                            ^^^
                                                            |||

      Wenn Du die da weglässt, sollte es funktionieren.

      Hier habe ich ja keine Maskierungen, die Maskierungen habe ich ja im Array und wenn ich die da weglasse, dann habe ich die Fehlermeldung "Compilation failed: nothing to repeat at offset 0".

      Oder habe ich Dich hier jetzt völlig missverstanden?

      Gruß
      Enrico

      1. Meinst Du damit die Angabe, mit der ein Suchmuster ersetzt werden soll?

        $Inhalt = preg_replace ('/' . $Zeichen [$i]. '+/', $Zeichen [$i], $Inhalt);
                                                              ^^^
                                                              |||

        Genau die. Du kannst z.B. zwei Arrays erstellen, eins mit und eins ohne Maskierung (nur zum Verständnis, da gibt es sicherlich bessere Möglichkeiten.

        Also z.B.

          
        $mitMaskierung = array('\?');  
        $ohneMaskierung = array('?');  
          
        $Inhalt = preg_replace ('/' . $mitMaskierung[$i]. '+/', $ohneMaskierung[$i], $Inhalt);  
        
        

        Gruß, Dennis

        1. Moin!

          Genau die. Du kannst z.B. zwei Arrays erstellen, eins mit und eins ohne Maskierung (nur zum Verständnis, da gibt es sicherlich bessere Möglichkeiten.

          Fail. Maskierung kriegt man durch Escaping. Und da gibts auch für preg-Funktionen eine entsprechende Funktion.

          - Sven Rautenberg

          1. Hallo Sven,

            Genau die. Du kannst z.B. zwei Arrays erstellen, eins mit und eins ohne Maskierung (nur zum Verständnis, da gibt es sicherlich bessere Möglichkeiten.

            Fail. Maskierung kriegt man durch Escaping. Und da gibts auch für preg-Funktionen eine entsprechende Funktion.

            so ganz versteh ich jetzt nicht, was Du mir da sagen willst!?

            Gruß, Dennis

            1. Moin!

              Genau die. Du kannst z.B. zwei Arrays erstellen, eins mit und eins ohne Maskierung (nur zum Verständnis, da gibt es sicherlich bessere Möglichkeiten.

              Fail. Maskierung kriegt man durch Escaping. Und da gibts auch für preg-Funktionen eine entsprechende Funktion.

              so ganz versteh ich jetzt nicht, was Du mir da sagen willst!?

              htmlspecialchars(), mysqli_real_escape_string(), preg_quote()...

              - Sven Rautenberg

              1. htmlspecialchars(), mysqli_real_escape_string(), preg_quote()...

                Dann hatte ich's doch richtig verstanden. So ist's natürlich besser, wie ich ja geschrieben hatte ("da gibt's bessere Möglichkeiten"), aber deshalb ist das mit den zwei Arrays ja noch lange nicht falsch. Es ging darum zu zeigen, warum "?" ausgegeben wird und nicht "?".

                Gruß, Dennis

        2. Hallo Dennis,

          $mitMaskierung = array('?');
          $ohneMaskierung = array('?');

          Ok, so funktioniert das ohne Warnung.

          Dann habe ich jetzt einen Ansatzpunkt :-)

          Danke Dir.

          Gruß
          Enrico

          1. Hello,

            $mitMaskierung = array('?');
            $ohneMaskierung = array('?');

            BTW:
            Interessant ist auch das:

              
            <?php  
              
            $mitMaskierung = array('\?', '\\?', '\\\?', '\\\\?');  
              
            echo "<pre>\r\n";  
            echo htmlspecialchars(print_r($mitMaskierung,1));  
            echo "</pre>\r\n";  
              
            ?>  
            
            

            Liebe Grüße aus dem schönen Oberharz

            Tom vom Berg

            --
             ☻_
            /▌
            / \ Nur selber lernen macht schlau
            http://bergpost.annerschbarrich.de
            1. Hallo Tom,

              Interessant ist auch das

              Hier bekomme ich folgende Anzeige:

              Array
                 (
                    [0] => ?
                    [1] => ?
                    [2] => \?
                    [3] => \?
                 )

              D.h. das Array wird wie definiert ausgegeben?!

              Verstehe nicht ganz, worauf Du hinaus willst.

              Gruß
              Enrico

              1. Hello,

                Interessant ist auch das

                Hier bekomme ich folgende Anzeige:

                Array
                   (
                      [0] => ?
                      [1] => ?
                      [2] => \?
                      [3] => \?
                   )

                D.h. das Array wird wie definiert ausgegeben?!

                Verstehe nicht ganz, worauf Du hinaus willst.

                War nur eine kleine Nebenbetrachtung zur Anzahl der per Zuweisung im Editor einzugebenen Backslashes. Hast Du mal gezählt?

                Liebe Grüße aus dem schönen Oberharz

                Tom vom Berg

                --
                 ☻_
                /▌
                / \ Nur selber lernen macht schlau
                http://bergpost.annerschbarrich.de
  2. Hello,

    Du könntest auch mit einem Array, trim() bzw. rtrim() und substring() arbeiten
    http://de.php.net/manual/en/function.trim.php

    Gucken, was das letzte Zeichen ist,
    solange es im Array der zu verkürzenden drinsteht, mit rtrim() abschneiden,
    das Zeichen in einem Stack (anderes Array) merken,
    mit dem Reststring weiterarbeiten

    Das ganze solagen, bis kein abzuschneidendes Zeichen mehr vorkommt am Ende.

    Dann den Stack wieder anhängen (in der gewünschten Orientierung)

    Fertig.

    Das ganze könnte dann auch Multibytefähig geschrieben werden.
    Dann benötigst Du mb_substr()
    http://de.php.net/manual/en/function.mb-substr.php
    und mb_strpos()
    http://de.php.net/manual/en/function.mb-strpos.php
    und mb_strlen()
    http://de.php.net/manual/en/function.mb-strlen.php
    um jeweils das letzte _Zeichen_ (_nicht_ Byte!) zu prüfen.

    Alternativ kannst Du Dir auch ein mb_explode() schreiben, dass den String  zuvor in ein Array von Zeichen (nicht Bytes!) zerlegt. Dann kannst Du anschließend eine Schleife mit array_pop()
    http://de.php.net/manual/en/function.array-pop.php
    aufbauen.

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
     ☻_
    /▌
    / \ Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
    1. Hallo Tom,

      auch Dir danke für Deine rasche Antwort.

      Wow, das sind ja reichlich(e) Alternativen.

      Ich befürchte allerdings, dass mein Gesamtvorhaben dann aber sehr schnell sehr unübersichtlich wird, da mein geschildertes Problem nur der Einstieg zu weiteren Bearbeitungsschritten ist:

      Schritt 1: Ersetze alle mehrfach hintereinander vorkommenden Satzzeichen gegen eines

      Schritt 2: Lösche jedes Leerzeichen vor einem Satzzeichen raus (außer bei runden Klammern)

      Schritt 3: Setze nach jedem Satzzeichen ein Leerzeichen (außer bei runden Klammern)

      Ich werde versuchen, erstmal meine Grundfunktionalität hinzubekommen und mich dann an's Feintuning zu machen.

      Vielleicht kann ich alle Schritte ja auch über ein bis zwei reguläre Ausdrücke umsetzen, das wäre meines Erachtens dann die kürzeste Lösung, aber da heisst es "basteln, basteln, basteln".

      Dürfte zwar nicht gerade der typische Weg sein, aber so komme ich (hoffentlich) an's Ziel.

      Gruß
      Enrico

      1. Hello,

        Schritt 3: Setze nach jedem Satzzeichen ein Leerzeichen (außer bei runden Klammern)

        Und was ist jetzt, wenn da steht:

        "Ich weiß nicht, ob das gut geht ???!!!"

        Was soll daraus werden?
        Meintest Du das so?

        "Ich weiß nicht, ob das gut geht? !"

        Anderenfalls sind Deine Forderungen in diese spezielle Funktion mit dem Stack garantiert leicht einzubauen und man versteht auch sofort, was Du willst.

        Denke an die Multibyte-Festigkeit!

        Sonst kannst Du deine Arbeit bald wieder wegwerfen, wenn nämlich nachher in UTF-8 codiert werden soll und Zeichen oberhalb vom Codepoint 127 benötigt werden.

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
         ☻_
        /▌
        / \ Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
  3. Hallo,

    so, ich bin jetzt schon ein gutes Stückchen weitergekommen, habe aber irgendwo noch einen Logik- und/oder Programmierfehler, den ich aber, nicht nur aufgrund der etwas vorangeschrittenen Uhrzeit, bedauerlicherweise nicht lokalisieren kann.

    Hier der Code:

    $Urspruenglicher_Text          = "Ein     beliebiger     Text       !!!?????";
       $Einzelne_Zeichen_Text         = preg_split ('//', $Urspruenglicher_Text, -1, PREG_SPLIT_NO_EMPTY);
       $Anzahl_Elemente_Text          = count ($Einzelne_Zeichen_Text);

    $String_Suche                  = " !?#&()*+,-./:;=@*";
       $Einzelne_Zeichen_Suche        = preg_split ('//', $String_Suche, -1, PREG_SPLIT_NO_EMPTY);
       $Anzahl_Elemente_Suche         = count ($Anzahl_Zeichen_Suche);

    $Satzzeichen_bereits_vorhanden = false;
       $Bearbeiteter_Text             = array ();

    for ($i = 0; $i < $Anzahl_Elemente_Text; $i++)
       {
          if (in_array ($Einzelne_Zeichen_Text [$i], $Einzelne_Zeichen_Suche))
          {
             $j = 1;

    while ($Einzelne_Zeichen_Text [$i + $j] == $Einzelne_Zeichen_Text [$i] and $Einzelne_Zeichen_Text [$i + $j] < $Anzahl_Elemente_Text)
             {
                $j += 1;
                $Satzzeichen_bereits_vorhanden = true;
             }

    if ($Satzzeichen_bereits_vorhanden == false)
             {
                array_push ($Bearbeiteter_Text, $Einzelne_Zeichen_Text [$i + $j]);
             }
          }
          else
          {
             array_push ($Bearbeiteter_Text, $Einzelne_Zeichen_Text [$i + $j]);
          }
       }

    Wenn ich mir mit "print_r ($Bearbeiteter_Text)" das Array anzeigen lasse, bekomme ich folgende Ausgabe, ich habe hierbei Bemerkungen eingefügt, die die fehlerhafte Ausgabe besser hervorheben:

    Array (
        [0] => E
        [1] => i
        [2] => n
       ----------> Ein Leerzeichen fehlt, "b" von "beliebiger" Text wurde verschluckt
        [3] => e
        [4] => l
        [5] => i
        [6] => e
        [7] => b
        [8] => i
        [9] => g
       [10] => e
       [11] => r
       [12] =>
       ----------> [12] scheint ein Leerzeichen zu sein, "T" von "Text" wurde verschluckt
       [13] => e
       [14] => x
       [15] => t
       [16] =>
       ----------> [16] scheint ein Leerzeichen zu sein, sämtliche Satzzeichen wurden verschluckt
       )

    Könnt ihr mir helfen, diesen ersten Schritt abzuschließen?

    Danach stehen noch weitere Bearbeitungsschritte an, dazu muß aber erstmal die Basis stimmen.

    Vielen Dank und Gruß
    Enrico

    1. Hello Enrico,

      so, ich bin jetzt schon ein gutes Stückchen weitergekommen, habe aber irgendwo noch einen Logik- und/oder Programmierfehler, den ich aber, nicht nur aufgrund der etwas vorangeschrittenen Uhrzeit, bedauerlicherweise nicht lokalisieren kann.

      Hier der Code:

      $Urspruenglicher_Text          = "Ein     beliebiger     Text       !!!?????";
         $Einzelne_Zeichen_Text         = preg_split ('//', $Urspruenglicher_Text, -1,

      PREG_SPLIT_NO_EMPTY);

      Bereits hier bin ich mir nicht mehr sicher, ob das auch multibytefest ist.
      http://de.php.net/manual/en/function.preg-split.php

      Ich würde heute keine Arbeit mehr auf eine Funktion verwenden, die nicht multibytefest wäre, wenn sie denn Bestand haben soll...

      Das mag erstmal sehr viel aufwändiger sein und muss bestimmt später, wenn die PHP-Entwickler ihren Vorgehensirrtum korrigiert haben, nochmal revidiert werden. Aber bis dahin ist bestimmt noch viiiiel Zeit.

      Liebe Grüße aus dem schönen Oberharz

      Tom vom Berg

      --
       ☻_
      /▌
      / \ Nur selber lernen macht schlau
      http://bergpost.annerschbarrich.de
      1. Hi!

        Bereits hier bin ich mir nicht mehr sicher, ob das auch multibytefest ist.
        Ich würde heute keine Arbeit mehr auf eine Funktion verwenden, die nicht multibytefest wäre, wenn sie denn Bestand haben soll...

        Es gibt für die preg-Funktionen den u-Modifizierer, der den zu durchsuchenden Wert als UTF-8-kodiert behandelt. Mehr Multibyte braucht man je eigentlich nicht.

        Der Weg, den du vorgeschlagen hast, ist im Gegensatz zu ordentlicher Maskierung deutlich aufwendiger. Warum schlugst du diesen vor?

        Lo!

        1. Hello,

          Bereits hier bin ich mir nicht mehr sicher, ob das auch multibytefest ist.
          Ich würde heute keine Arbeit mehr auf eine Funktion verwenden, die nicht multibytefest wäre, wenn sie denn Bestand haben soll...

          Es gibt für die preg-Funktionen den u-Modifizierer, der den zu durchsuchenden Wert als UTF-8-kodiert behandelt. Mehr Multibyte braucht man je eigentlich nicht.

          Den klein-u-Modifier hatte ich wohl verdrängt :-)

          Der Weg, den du vorgeschlagen hast, ist im Gegensatz zu ordentlicher Maskierung deutlich aufwendiger. Warum schlugst du diesen vor?

          Ich finde es immer gut, wenn man noch eine Alternative kennt und weiß, welchen Aufwand eine Funktion im Hintergrund so treiben muss. Die REM muss ja bestimmt auch ganz schön schuften, um das Gewünschte zu erreichen.

          Würde mich interessieren, welche Lösung mehr Kraft kostet.

          Pflegeleichter ist nachher sicherlich diejenige mit Regular Expressions, sofern man sie gut dokumentiert.

          Liebe Grüße aus dem schönen Oberharz

          Tom vom Berg

          --
           ☻_
          /▌
          / \ Nur selber lernen macht schlau
          http://bergpost.annerschbarrich.de
          1. Hallo Tom,

            ich versteh nur noch Bahnhof, von dem, was ihr hier besprecht.

            Ich dachte immer, wenn man mit Zeichen als solche arbeitet, dann paßt das, aber dass man auch noch auf die Multibyte-Fähigkeit (?) achten sollte oder dergleichen... Ein Buch mit mehr als sieben Siegeln für mich... :-|

            Gruß
            Enrico

            1. Hi!

              Ich dachte immer, wenn man mit Zeichen als solche arbeitet, dann paßt das, aber dass man auch noch auf die Multibyte-Fähigkeit (?) achten sollte oder dergleichen... Ein Buch mit mehr als sieben Siegeln für mich... :-|

              PHP geht üblicherweise davon aus, dass ein Zeichen ein Byte belegt. Das tuts aber nicht in jedem Fall, weil man nicht immer nur mit 256 Zeichen auskommt. Ausführlich im Kapitel Grundlagen/Zeichenkodierung und geschriebene Sprache.

              Lo!

              1. Hallo dedlfix,

                Ausführlich im Kapitel Grundlagen/Zeichenkodierung und geschriebene Sprache

                Danke für den Link.

                Gruß
                Enrico

    2. Hey Enrico,

      ich glaube das ist viel zu kompliziert. Schau Dir das mal an:

        
      <?php  
        
      $subject = "Ein    beliebiger  Text       !!!?????";  
        
      $replacementArray = array(' ', '!', '?', '#', '&', '(', ')', '*', '+', ',', '-', '.', ':', ';', '=', '@', '*');  
        
      $searchArray = array();  
        
      foreach ($replacementArray as $replacement) {  
      	array_push($searchArray, '/' . preg_quote($replacement) . '+/');  
      }  
        
      echo preg_replace($searchArray, $replacementArray, $subject);  
      
      

      Gruß, Dennis

      1. Hallo Dennis & Tom,

        danke für eure Antworten.

        Da ich jetzt weg muss und meinem Kumpel beim Vereinsheim-Innen-Weiter-Ausbauen helfe, werde ich mir eure Antworten dann anschauen, wenn ich wieder da bin.

        Gruß
        Enrico