Ben: Bei "explode" entstehen Leerzeichen

N Abend allerseits,

folgendes Problem verfolgt mich blöderweise:

Wenn ich ein Textarea nach Zeilenumbrüchen explode entstehen jeweils am Zeilenende Leerzeichen die ich nicht brauchen kann.

$array = explode("\n",$suchwoerter);

Wenn ich jetzt durchführe:
if(preg_match("/\s+/",$array[$i])) {
echo "Leerzeichen gefunden";
}

..findet er in jedem Falle ein Leerzeichen.
Mit preg_replace die Leerzeichen einfach entfernen ist leider etwas ungeschickt, da ich dann keine Kontrolle mehr hätte ob innerhalb der einzelnen Wörter noch ein Leerzeichen vorhanden war.

Könnt ihr mir helfen?

Danke allen
Gruß

  1. Hi,

    Wenn ich ein Textarea nach Zeilenumbrüchen explode entstehen jeweils am Zeilenende Leerzeichen die ich nicht brauchen kann.

    Du "explodest" augenscheinlich nicht nach Zeilenumbrüchen, sondern nach Teilen davon.

    $array = explode("\n",$suchwoerter);

    "\n" ist ein unter Unixoiden üblicher Zeilenumbruch. Bei Windows ist es "\r\n", auf dem Mac "\r"[1].

    Cheatah

    [1] Zumindest war das früher so. Ich weiß nicht, wie es bei Mac OS X ist.

    --
    X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. Wenn ich ein Textarea nach Zeilenumbrüchen explode entstehen jeweils am Zeilenende Leerzeichen die ich nicht brauchen kann.

      Du "explodest" augenscheinlich nicht nach Zeilenumbrüchen, sondern nach Teilen davon.

      $array = explode("\n",$suchwoerter);

      "\n" ist ein unter Unixoiden üblicher Zeilenumbruch. Bei Windows ist es "\r\n", auf dem Mac "\r"[1].

      Wie explode ich denn komplett nach Umbrüchen? Mit jeder anderen Version hab ich es nicht hinbekommen. Genausowenig wie ich es hinbekommen habe statt \s -> [:space:] zu benutzen, obwohl überall steht, dass das funktionieren sollte.

      Danke schonmal

      1. Hallo,

        Wie explode ich denn komplett nach Umbrüchen? Mit jeder anderen Version hab ich es nicht hinbekommen.

        (\r\n|\r|\n)

        (\r\n muss am Anfang stehen, damit er das zuerst erkennt und danach erst nach \r oder \n alleine sucht)

        Genausowenig wie ich es hinbekommen habe statt \s -> [:space:] zu benutzen, obwohl überall steht, dass das funktionieren sollte.

        Weil das [[:space:]] heißt. Der Witz ist, dass man bei Perl-kompatiblen regulären Ausdrücken \s sowohl direkt schreiben kann als auch in Zeichenklassen - d.h. [abc\s] würde alle Leerzeichen und die Buchstaben a, b nud c matchen. Wenn Du jetzt innerhalb einer Zeichenklasse \s durch [:space:] ersetzt, erhälst Du das richtige Ergebnis, d.h. [abc[:space:]] würde genauso wie [abc\s] funktionieren. Und wenn Du das \s allein ersetzen willst, dann musst Du halt ne Zeichenklasse draus machen, d.h. [[:space:]].

        Allerdings: Wenn Du sowieso preg_* (also preg_match, preg_split, ...) nimmst, dann würde ich auf die POSIX-Zeichenklassen [:...:] verzichten - sie machen den Ausdruck in meinen Augen durch ihre Größe einfach nur unübersichtlich und bei \s sieht man zumindest meiner Meinung besser, was gemeint ist (zumal man sich bei \s keine Sorgen um die Klammerung oder so machen muss).

        Ferner: Für z.B. das extrem nützliche \b gibt's keine Entsprechung in der POSIX-Syntax, weswegen man dann zwei verschiedene Syntax-Arten mischen müsste, um beides zu verwenden, was noch ein Grund ist, davon abzuraten.

        Viele Grüße,
        Christian

        1. Vielen Dank schonmal.
          Wie muss denn der Explode Befehl mit mehreren Delimitern aussehen?

          explode("(\r\n|\r|\n)",$suchwoerter) funktioniert irgendwie nicht und alle anderen Varianten die ich so getestet habe auch nicht.

          1. Hallo,

            Wie muss denn der Explode Befehl mit mehreren Delimitern aussehen?

            Oh, ich dachte es wäre klar, dass Du hier preg_split nehmen musst, damit Du einen regulären Ausdruck angeben kannst (explode nimmt nur Strings entgegen):

            $foo = preg_split ("/\r\n|\r|\n/", $bar);

            Viele Grüße,
            Christian

            1. Lieber Christian,

              $foo = preg_split ("/\r\n|\r|\n/", $bar);

              ich habe mir angewöhnt, in PHP einen anderen Delimiter einzusetzen, da das Handling von URLs dadurch einfacher gelingt, da ich den Slash in URLs ansonsten escapen müsste.

              $foo = preg_split ('~\r\n|\r|\n~', $bar); // RegEx darf auch in einfachen Quotes stehen

              In JavaScript nützt mir das natürlich nichts, da dort die direkte Notation von RegExp-Objekten nur mit Slashes geht (ich glaube mittlerweile nennt man genau das einen "Design-Fehler" an JS).

              Noch ein Gedanke: Was spricht eigentlich gegen folgende Lösung (sie entfernt allerdings auch Leerzeilen)?

              $foo = preg_split('~[\r\n]+~', $bar);

              Liebe Grüße aus Ellwangen,

              Felix Riesterer.

              --
              ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
              1. Hallo Felix,

                $foo = preg_split ("/\r\n|\r|\n/", $bar);

                ich habe mir angewöhnt, in PHP einen anderen Delimiter einzusetzen, da das Handling von URLs dadurch einfacher gelingt, da ich den Slash in URLs ansonsten escapen müsste.

                Naja, bei Pfaden und URLs nehme ich auch was anderes, aber ansonsten kann ich mit / gut leben. Ist wohl Geschmackssache.

                In JavaScript nützt mir das natürlich nichts, da dort die direkte Notation von RegExp-Objekten nur mit Slashes geht

                Was spricht gegen new RegExp ("^hallo$") wenn viele "/" enthalten sein sollen? Sieht viellecht nicht so "chick" aus, funktioniert aber genauso.

                Noch ein Gedanke: Was spricht eigentlich gegen folgende Lösung (sie entfernt allerdings auch Leerzeilen)?

                Du beantwortest Deine Frage gerade selbst. ;-)

                Viele Grüße,
                Christian

              2. Hi,

                In JavaScript nützt mir das natürlich nichts, da dort die direkte Notation von RegExp-Objekten nur mit Slashes geht (ich glaube mittlerweile nennt man genau das einen "Design-Fehler" an JS).

                JavaScript ist objetktorientiert, d.h. man benötigt ein RegExp-Objekt, um mit einer Regular Expression zu arbeiten. Dies geht, wie Christian schon sagte, hervorragend mit new RegExp(). Das es zusätzlich eine Kurzschreibweise gibt, sollte Dich eigentlich freuen. Oder erwartest Du, dass der JS-Interpreter in

                var foo = {bar:".+"}.test('bar');

                irgendwo eine Regular Expression erkennt?

                Noch ein Gedanke: Was spricht eigentlich gegen folgende Lösung (sie entfernt allerdings auch Leerzeilen)?
                $foo = preg_split('~[\r\n]+~', $bar);

                Dagegen spricht, dass dadurch die Anzahl der gefundenen Umbrüche bis zu dem doppelten der eingegebenen entspricht.

                Cheatah

                --
                X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
                X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
                X-Will-Answer-Email: No
                X-Please-Search-Archive-First: Absolutely Yes
                1. Lieber Cheatah,

                  Das es zusätzlich eine Kurzschreibweise gibt, sollte Dich eigentlich freuen. Oder erwartest Du, dass der JS-Interpreter in

                  var foo = {bar:".+"}.test('bar');

                  irgendwo eine Regular Expression erkennt?

                  Ja, ich habe anscheinend bisher noch nicht begriffen, dass /bar/ eine Kurzschreibweise für ein Objekt ist... Und wenn ich mir den ASCII-Zeichenvorrat anschaue, der für solche Bedeutungen wie Objekt-einleiten verfügbar ist, dann sehe ich auch ein, dass man das kaum mit anderen Zeichen schreiben könnte, denn fast alle anderen Interpunktions- oder sonstige Zeichen tragen bereits (z.T. mehrfach) andere Bedeutungen.

                  $foo = preg_split('~[\r\n]+~', $bar);

                  Dagegen spricht, dass dadurch die Anzahl der gefundenen Umbrüche bis zu dem doppelten der eingegebenen entspricht.

                  Naja, ich habe es nie ausprobiert. Hätte ich vielleicht tun sollen. Meiner Erwartung nach hätte es die Umbrüche eher vermindern sollen, da eine Zeichenfolge wie diese nach meiner Erwartung in nur drei Array-Elemente zerlegt werden würde:

                  $foo = preg_split('~(?s)[\r\n]+~', "ersteZeile\r\n\r\ndritteZeile\nvierteZeile");

                  Aber ich werde das in Zukunft einmal ausprobieren, wenn ich es einmal benötigen sollte.

                  Liebe Grüße aus Ellwangen,

                  Felix Riesterer.

                  --
                  ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
                  1. Servus,

                    Meiner Erwartung nach hätte es die Umbrüche eher vermindern sollen, da eine Zeichenfolge wie diese nach meiner Erwartung in nur drei Array-Elemente zerlegt werden würde:

                    $foo = preg_split('~(?s)[\r\n]+~', "ersteZeile\r\n\r\ndritteZeile\nvierteZeile");

                    Dem ist auch so. Cheatah hat wahrscheinlich (wie ich zuerst auch ;) einmal zuviel gedacht und nicht berücksichtigt, dass Regex per default gierig sind.

                    Gruss
                    Patrick

                    --
                    sh:( fo:| ch:? rl:( br:> n4:( ie:% mo:) va:} de:> zu:) fl:| ss:| ls:[ js:|
                    1. Hi,

                      $foo = preg_split('~(?s)[\r\n]+~', "ersteZeile\r\n\r\ndritteZeile\nvierteZeile");
                      Dem ist auch so. Cheatah hat wahrscheinlich (wie ich zuerst auch ;) einmal zuviel gedacht und nicht berücksichtigt, dass Regex per default gierig sind.

                      nein, ich habe neben den ungewöhnlichen Delimitern einfach das + übersehen. Somit ist es immer noch nicht wie gewünscht, aber anders herum als ich sagte: Beliebig viele wirkliche Umbrüche werden als ein einziger erkannt.

                      Cheatah

                      --
                      X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
                      X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
                      X-Will-Answer-Email: No
                      X-Please-Search-Archive-First: Absolutely Yes
                      1. Servus,

                        nein, ich habe neben den ungewöhnlichen Delimitern einfach das + übersehen. Somit ist es immer noch nicht wie gewünscht, aber anders herum als ich sagte: Beliebig viele wirkliche Umbrüche werden als ein einziger erkannt.

                        Ok, dann eben so ;) Dieses Verhalten hat aber Felix bereits angemerkt mit

                        sie entfernt allerdings auch Leerzeilen

                        Was möglicherweise nicht von Ben gewünscht war, aber in anderen Situationen durchaus wünschenswert sein kann :)

                        Gruss
                        Patrick

                        --
                        sh:( fo:| ch:? rl:( br:> n4:( ie:% mo:) va:} de:> zu:) fl:| ss:| ls:[ js:|