Sonja Demount: [php] im Sting alles zwischen Klammern entfernen.

Hallo,

ich habe einen String mit mehreren Klammern:

"sich abmühen, sich abplagen, sich abquälen, sich placken, sich plagen, sich schinden, sich verbrauchen; (umgangssprachlich) sich abschinden, sich abschuften, sich abstrampeln, sich abzappeln, ackern, rackern, schuften; (salopp) sich abrackern; (süddeutsch, österreichisch umgangssprachlich) sich abfretten, sich fretten; (südwestdeutsch, schweizerisch) sich abschaffen; (landschaftlich) sich abplacken"

Ich habe ein Regexcode gefunden:

$with = "dankling(Daniel Kling)"; $regexp = '^([a-zA-Z0-9 ]+)\(.+$'; $replace = ""; $without = eregi_replace( $regexp, "\\1", $with ); echo "<p>Vorher: ".$with."</p>"; echo "<p>Nachher: ".$without."</p>";

Der in dieser Konstelation funktioniert es füge ich aber meinen String (Siehe oben) ein , ändert sich nichts, die Klammern sind weiterhin vorhanden.

    1. Tach!

      Ich habe ein Regexcode gefunden:

      Prüf doch mal, was der tut.

      Das ist aber nicht der passende Tester. Oder anders gesagt: Dieser Tester passt nicht auf die veraltete (seit PHP 5.3 missbilligte und in PHP 7.0 entfernte) Funktion in dem von Sonja gefundenen Code. preg_replace() wäre das aktuelle Äquivalent. Die Syntax der regulären Ausdrücke unterschiedet sich auch zwischen diesen beiden Funktionen.

      dedlfix.

  1. Deine Regex macht nicht was du willst, da steht grob gesagt: Guck nach alphanumerischem Zeichen am Anfang des Strings und ersetze alles ab der ersten Klammer durch nichts. Wenn du alles innerhalb inkl. Klammern ersetzen willst geht das einfacher, musst aber halt escapen:

    https://3v4l.org/WLlvN

    und eregi wird zukünftig nicht mehr unterstützt.

    1. Vielen Dank die Lösung mit Preg_replace war hilfreich. Wenn ich dich richtig verstanden habe wird preg_replace auch in PHP 7 noch unterstützt?

      1. Das Manual selbst sagt: PHP 4, PHP 5, PHP 7 Generell wurde ereg durch preg abgelöst, das ist also der aktuelle Stand der Technik.

  2. Hi,

    "sich abmühen, sich abplagen, sich abquälen, sich placken, sich plagen, sich schinden, sich verbrauchen; (umgangssprachlich) sich abschinden, sich abschuften, sich abstrampeln, sich abzappeln, ackern, rackern, schuften; (salopp) sich abrackern; (süddeutsch, österreichisch umgangssprachlich) sich abfretten, sich fretten; (südwestdeutsch, schweizerisch) sich abschaffen; (landschaftlich) sich abplacken"

    Ich habe ein Regexcode gefunden:

    $with = "dankling(Daniel Kling)"; $regexp = '^([a-zA-Z0-9 ]+)\(.+$'; $replace = ""; $without = eregi_replace( $regexp, "\\1", $with ); echo "<p>Vorher: ".$with."</p>"; echo "<p>Nachher: ".$without."</p>";

    Die eregi-Funktionen sind m.W. auf der Abschußliste, also am besten nicht mehr frisch einbauen, wenn, dann die preg-Funktionen verwenden.

    Der Ausdruck sucht vom Stringanfang an nach den Buchstaben a bis z, A-Z oder Ziffern oder Leerzeichen, gefolgt von einer öffnenden runden Klammer gefolgt von beliebigen Zeichen bis zum Ende.

    Und schmeißt beim Ersetzen alles ab der öffnenden Klammer weg.

    Das paßt also überhaupt nicht zu Deinem Problem. Du hast auch andere Zeichen, die erhalten bleiben sollen (Satzzeichen, Umlaute, Scharfes s, ...).

    Und Du willst auch nicht ab der ersten öffnenden Klammer alles bis zum Ende wegwerfen.

    Was Du willst: eine öffnende Klammer finden, gefolgt von beliebigen Zeichen außer der schließenden Klammer, gefolgt von der schließenden Klammer, und das ganze dann durch nichts ersetzen.

    Also "\([^)]\)" suchen und durch nichts ersetzen.

    Ggf. auch noch ein Leerzeichen nach der schließenden Klammer, also "\([^)]\) ?"

    cu,
    Andreas a/k/a MudGuard

    1. @@MudGuard

      Ggf. auch noch ein Leerzeichen nach der schließenden Klammer, also "\([^)]\) ?"

      Eher das vor der öffnenden Klammer, also "\s*\([^)]\)?"

      Dann passt’s auch auf „sich abmühen, sich abschinden (umgangssprachlich), sich abplagen“.

      LLAP 🖖

      -- “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
      1. Hab ich Regex nicht kapiert?

        Du suchst nach Leerraum, eine Klammer auf, einmal NICHT-Klammer-zu und einer optionalen Klammer-zu?!?

        Rolf

        1. Hallo Rolf,

          Hab ich Regex nicht kapiert?

          Du suchst nach Leerraum, eine Klammer auf, einmal NICHT-Klammer-zu und einer optionalen Klammer-zu?!?

          Nein, in diesem Punkt hast du recht. Da fehlt der Quantifier.

          LG,
          CK

          -- https://wwwtech.de/about
        2. @@Rolf b

          Hab ich Regex nicht kapiert?

          Nö. Ich hab nicht genau hingesehen. Ich hatte in MudGuards Ausdruck lediglich das Leerzeichen verschoben ohne das fehlende * zu berichtigen.

          LLAP 🖖

          -- “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
        3. Hi,

          Du suchst nach Leerraum, eine Klammer auf, einmal NICHT-Klammer-zu und einer optionalen Klammer-zu?!?

          Sorry, den Quantifier hatte ich vergessen. War heute früh etwas aufgeregt, da ich heute früh kurz vor meiner ersten MRT-Untersuchung war …

          cu,
          Andreas a/k/a MudGuard

      2. Hi,

        Eher das vor der öffnenden Klammer, also "\s*\([^)]*\)?"

        Dann passt’s auch auf „sich abmühen, sich abschinden (umgangssprachlich), sich abplagen“.

        Mist, ich hätte die zwei Aufrufe von string_reverse (vor und nach dem Ersetzen) doch nicht weglassen sollen 😉

        cu,
        Andreas a/k/a MudGuard

    2. Ggf. auch noch ein Leerzeichen nach der schließenden Klammer, also "\([^)]\) ?"

      Ich glaube, da warst Du etwas zu eilig. Diese Regex findet: Eine Klammer-auf, EIN Zeichen, das nicht Klammer-zu ist, eine Klammer-zu und eventuell ein Space. Also zum Beispiel "(x)" oder "(y) ", aber nicht "(hallo)". Es fehlt ein + hinter der rechten eckigen Klammer.

      Aber nicht nur. Man muss noch auf die Gierigkeit der Quantifizierer aufpassen Ein Pattern wie \([^)]+\) findet in "Das ist (heute) nicht (naja) bestes Wetter" den Substring "(heute) nicht (naja)". Um das zu verhindern, muss man dem Quantifizierer die Gier abgewöhnen, entweder durch ein nachgestelltes Fragezeichen am Quantifizierer oder durch die lokale Regex-Option U.

      Das Pattern wäre also "/\s([^)]?)\s*/U", sprich: eventuell Leerraum, dann der Klammerausdruck, dann eventuell nochmal Leerraum. Und dann die U Option. Achtung, großes U, das kleine u ist für UTF-8. Als Ersatz-String nimmst Du ein einzelnes Space, damit Du nach Ersetzen nicht mehrere Leerstellen im String hast. Ganz sauber ist es nicht, wenn z.B. ein Satzzeichen direkt hinter der Klammergruppe steht, hast Du nachher eine Leerstelle vor dem Satzzeichen. Wie man das genau feintuned, habe ich mir jetzt nicht überlegt. Eventuell reicht es, nur die Leerräume VOR der Klammergruppe zu matchen.

      Was damit nicht funktioniert, sind Strings mit geschachtelten Klammern. Dafür bräuchtest Du vermutlich rekursive Regexe, aber damit kenne ich mich nicht aus. Wenn Du solche Strings ausschließen kannst, ist alles gut. Natürlich könntest Du auch eine Regex bauen die sowas erkennt 😉

      Rolf

      1. Hallo Rolf,

        Aber nicht nur. Man muss noch auf die Gierigkeit der Quantifizierer aufpassen Ein Pattern wie \([^)]+\) findet in "Das ist (heute) nicht (naja) bestes Wetter" den Substring "(heute) nicht (naja)". Um das zu verhindern, muss man dem Quantifizierer die Gier abgewöhnen, entweder durch ein nachgestelltes Fragezeichen am Quantifizierer oder durch die lokale Regex-Option U.

        Nein, das stimmt nicht. /\([^)]+\)/ findet: Klammer-auf, alles ausser Klammer zu, Klammer zu. Die schliessende Klammer nach „heute” ist also die Abbruchbedingung, die auch durch Greedyness nicht umgangen werden kann.

        Das Pattern wäre also "/ ([^)]?) */U", sprich: eventuell Leerraum, dann der Klammerausdruck, dann eventuell nochmal Leerraum.

        Damit entfernst du alle Spaces zwischen den Wörtern. Das erste ` *` muss weg. Und bzgl. des U habe ich ja oben schon etwas geschrieben.

        LG,
        CK

        -- https://wwwtech.de/about
        1. Hast recht, ich habe zu sehr an [] Ausdrücke ohne ^ gedacht. Aber Leerzeichen lösche ich nicht - du hast zu früh mit dem Zitieren aufgehört. Ich hatte das " " als Replacement vorgeschlagen :).

          Wobei Gunnar die Lösung gepostet hat, während ich schrieb: Man ersetzt nur den Leerraum vor den Klammern.

          Rolf

          1. Hallo Rolf,

            Aber Leerzeichen lösche ich nicht - du hast zu früh mit dem Zitieren aufgehört. Ich hatte das " " als Replacement vorgeschlagen :).

            Stimmt, überlesen. Sorry.

            LG,
            CK

            -- https://wwwtech.de/about
      2. @@Rolf b

        \([^)]+\)

        Ich würde * statt + nehmen, dann werden auch die Klammern bei „foo () bar“ entsorgt.

        LLAP 🖖

        -- “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory