Robert: Zugriff auf x-tes Zeichen im Sting

Hallöle,

gibt es eine einfachere Methode in Perl, auf das x-te Zeichen eines Strings zuzugreifen als die substr-Methode?

$x = 17;
$str = "Es begab sich aber zu der Zeit, daß ein Gebot von Kaiser Augustus ...";
$c = substr($str, 17, 1);
erscheint mir irgendwie "unperlisch" und ineffektiv.
Ich muß einen String Zeichen für Zeichen durchgehen und abhängig vom jeweiligen Zeichen diverse Aktionen ausführen ...

cu,
Robert

  1. Hallo Robert,

    gibt es eine einfachere Methode in Perl, auf das x-te Zeichen eines Strings zuzugreifen als die substr-Methode?

    soweit ich weiß, gibt es keine Möglichkeiten wie in python (var[17,1]) oder php ($var{17}/$var[17]).

    $x = 17;
    $str = "Es begab sich aber zu der Zeit, daß ein Gebot von Kaiser Augustus ...";
    $c = substr($str, 17, 1);
    erscheint mir irgendwie "unperlisch" und ineffektiv.
    Ich muß einen String Zeichen für Zeichen durchgehen und abhängig vom jeweiligen Zeichen diverse Aktionen ausführen

    dafür gibt es reguläre Ausdrücke http://perldoc.perl.org/perlreref.html/http://de.selfhtml.org/perl/sprache/regexpr.htm.

    Gruß aus Berlin!
    eddi

    --
    Wer Rechtschreibfehler findet, darf sie behalten.
    1. $x = 17;
      $str = "Es begab sich aber zu der Zeit, daß ein Gebot von Kaiser Augustus ...";
      $c = substr($str, 17, 1);
      erscheint mir irgendwie "unperlisch" und ineffektiv.
      Ich muß einen String Zeichen für Zeichen durchgehen und abhängig vom jeweiligen Zeichen diverse Aktionen ausführen

      dafür gibt es reguläre Ausdrücke http://perldoc.perl.org/perlreref.html/http://de.selfhtml.org/perl/sprache/regexpr.htm.

      Die aber wesntlich uneffektiver sind, wenn es nur darum geht ein Zeichne an der x-Stelle zu ermitteln.

      Wenn er jede einzelne Stelle ermitteln will, ist es wohl besser den String erst zu splitten und dann mit dem Array zu arbeiten.

      my @str = split //, $str;
      $c = $str[17];

      Struppi.

      1. Hallöle,

        Wenn er jede einzelne Stelle ermitteln will, ist es wohl besser den String erst zu splitten und dann mit dem Array zu arbeiten.
        my @str = split //, $str;
        $c = $str[17];

        Ah, das sieht interessant aus. Einmal den String zum Array splitten, und dann zigmal das Array direkt benutzen ...

        Mich wundert aber, daß es in Perl keinen direkten Zugriff gibt ...

        cu,
        Robert

        1. Moin!

          my @str = split //, $str;
          $c = $str[17];

          Ah, das sieht interessant aus. Einmal den String zum Array splitten, und dann zigmal das Array direkt benutzen ...

          Mich wundert aber, daß es in Perl keinen direkten Zugriff gibt ...

          Das könnte daran liegen, dass der "direkte Zugriff auf ein Zeichen" in Perl gar nicht so trivial realisierbar ist, wie es ausschaut.

          Zuerst denkt man ja: Ein Zeichen == Ein Byte, also einfach Stringposition plus Offset berechnen, und den dort gefundenen Bytecode als Zeichen behandeln.

          Da Perl seit Version 5.8 aber Strings intern als UTF-8 speichert, wenn es notwendig ist, gilt die Zuordnung Zeichen==Byte nicht mehr - die Berechnung des Offsets wird wesentlich aufwendiger, und die Sache insgesamt kompliziert.

          Erst wenn Strings intern als UTF-32 gespeichert werden würden, würde wieder ein konstantes Verhältnis gelten: 1 Zeichen == 4 Byte. Damit würde man allerdings den Speicherbedarf von normalen westeuropäischen Texten vervierfachen, ohne irgendeinen Mehrwert dafür zu erhalten.

          - Sven Rautenberg

          --
          My sssignature, my preciousssss!
          1. Hi,

            Das könnte daran liegen, dass der "direkte Zugriff auf ein Zeichen" in Perl gar nicht so trivial realisierbar ist, wie es ausschaut.
            Zuerst denkt man ja: Ein Zeichen == Ein Byte, also einfach Stringposition plus Offset berechnen, und den dort gefundenen Bytecode als Zeichen behandeln.
            Da Perl seit Version 5.8 aber Strings intern als UTF-8 speichert, wenn es notwendig ist, gilt die Zuordnung Zeichen==Byte nicht mehr - die Berechnung des Offsets wird wesentlich aufwendiger, und die Sache insgesamt kompliziert.

            Naja, ob das intern einfach ist, dürfte doch keine Rolle spielen - wenn es danach ginge, dürften Dinge wie m//, s/// usw. in Perl eigentlich nicht existieren, denn die sind doch wesentlich aufwendiger zu implementieren ;-)

            Auszug aus der Perl-Doku:

            Description:
            Perl is a language optimized for scanning arbitrary text files, extracting information from those text files [...]
            The language is intended to be practical (easy to use, efficient, complete) rather than beautiful (tiny, elegant, minimal).

            Gerade das "easy to use" (aber auch das "complete") ist _hier_ (also bezogen auf n-tes Zeichen des Strings) aber m.E. nicht erfüllt - beim "scanning of text files" kommt es durchaus öfter vor, daß eben das n-te Zeichen eines Strings benötigt wird ...

            cu,
            Andreas

            --
            Warum nennt sich Andreas hier MudGuard?
            Schreinerei Waechter
            Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
            1. Gerade das "easy to use" (aber auch das "complete") ist _hier_ (also bezogen auf n-tes Zeichen des Strings) aber m.E. nicht erfüllt - beim "scanning of text files" kommt es durchaus öfter vor, daß eben das n-te Zeichen eines Strings benötigt wird

              Dazu existiert doch substr, was ist daran nicht easy?

              Man kann die Funktion sogar verwenden um einzelne Zeichen oder Teilbereiche zu ersetzen. Sie ist also einfach zu gebrauchen und komplett mit alle Funktionen die man für die meisten Stringmanipulationen braucht.

              my $str = "abcde";
              substr( $str, 2, 1) = 'X';
              print $str;

              Struppi.

              1. Hi,

                Gerade das "easy to use" (aber auch das "complete") ist _hier_ (also bezogen auf n-tes Zeichen des Strings) aber m.E. nicht erfüllt - beim "scanning of text files" kommt es durchaus öfter vor, daß eben das n-te Zeichen eines Strings benötigt wird

                Dazu existiert doch substr, was ist daran nicht easy?

                easy to use wäre m.E. $str[17] - also so, wie in Javascript alert("hallo"[1]) der Zugriff auf ein Zeichen eines Strings einfach per angehängtem Index geht.

                cu,
                Andreas

                --
                Warum nennt sich Andreas hier MudGuard?
                Schreinerei Waechter
                Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
                1. Dazu existiert doch substr, was ist daran nicht easy?

                  easy to use wäre m.E. $str[17] - also so, wie in Javascript alert("hallo"[1]) der Zugriff auf ein Zeichen eines Strings einfach per angehängtem Index geht.

                  Das geht nicht in allen Browsern (deshalb nutze ich das nie) und liegt daran, dass  in Javascript ähnlich wie in Java fast alles ein Objekt ist.

                  Und dort geht dann der umgekehrte Weg nicht mehr:
                  var s = "abc";
                  s[2] = 'X';
                  alert(s); // 'abc'

                  Versuch mal mit JS das x.Zeichen auszutauschen. Da finde ich den Weg in Perl easy.

                  Es ist also nicht easy (da nicht immer funktionsfähig) und nicht komplett

                  Es gibt aber noch einen praktischen Grund, in Perl kann es nicht funktionieren, da der Interpreter dann nicht mehr zwischen einem Array und einem Skalar unterscheiden könnte und wenn man wirklich geil auf diese Schreibweise ist bleibt immer noch der Weg den String in ein Array zu splitten.

                  Struppi.

    2. Hallöle,

      soweit ich weiß, gibt es keine Möglichkeiten wie in python (var[17,1]) oder php ($var{17}/$var[17]).

      Sch... ...ade

      Ich muß einen String Zeichen für Zeichen durchgehen und abhängig vom jeweiligen Zeichen diverse Aktionen ausführen
      dafür gibt es reguläre Ausdrücke http://perldoc.perl.org/perlreref.html/http://de.selfhtml.org/perl/sprache/regexpr.htm.

      Naja, man kann zwar in Perl Code im regulären Ausdruck unterbringen, aber dennoch halte ich die Methode (in meinem Fall) für suboptimal - denn je nach Zeichen wird ziemlich viel Code ausgeführt ...
      Wenn es nur darum ginge, diverse Zeichen zu ersetzen, wär's was anderes.

      cu,
      Robert