Danni: Text splitten

Hallo,
ich suche eine "elegante" Möglichkeit, einen beliebigen Text nach folgenden Kriterien in Teiltexte aufzuteilen:
1. Zwischen der 40. und 50. Stelle aufteilen an der ersten dort auftretenden
   Leerstelle.
   Falls dort keine Leerstelle, an der nach der 50. Stelle brutal trennen.
2. Mit dem Text nach der Trennung verfahren wie unter 1.
Habt Ihr eine Idee oder gar ein ähnliches Beispielprogramm?
Berücksichtigt bitte bei Eurer Hilfe, dass ich noch nicht sehr gut bin in Perl.
Servus
Danni

  1. Hallo, muß es eine Perl-Lösung sein?

    Falls php auch geht, schau Dir folgende Befehle an:
    stripos oder strpos
    substr
    strlen
    eventuell auch: wordwrap und explode
    Daraus und mit einer Schleife sollte man das machen können. Lösungen gibt es viele.

    1. Hallo, muß es eine Perl-Lösung sein?

      Ja, sonst ka i nex!

      1. Ja, sonst ka i nex!

        I ka ka Perl.

  2. gudn tach!

    ich suche eine "elegante" Möglichkeit, einen beliebigen Text nach folgenden Kriterien in Teiltexte aufzuteilen:

    1. Zwischen der 40. und 50. Stelle aufteilen an der ersten dort auftretenden
         Leerstelle.
         Falls dort keine Leerstelle, an der nach der 50. Stelle brutal trennen.
    2. Mit dem Text nach der Trennung verfahren wie unter 1.
      Habt Ihr eine Idee oder gar ein ähnliches Beispielprogramm?

    fuer den anfang waere vielleicht http://search.cpan.org/perldoc?Text::Wrap etwas fuer dich.

    wenn du's aber alles von hand programmieren willst, waere ein vorschlag:

    $_ = $string;  
    my $out = '';  
    while(/\G(.{40}\S{0,10})/gc){  
      $out.= $1,"\n";  
    }  
    $out.= substr $_, pos;
    

    hab's nicht ausprobiert. so in etwa koennte es aber funzen.

    erklaerung der while-zeile gibt es in
    http://perldoc.perl.org/perlre.html (grundlagen) und
    http://perldoc.perl.org/perlop.html (beispiel)

    prost
    seth

    1. gudn tach!

      Ebenfalls!

      wenn du's aber alles von hand programmieren willst, waere ein vorschlag:

      $_ = $string;

      my $out = '';
      while(/\G(.{40}\S{0,10})/gc){
        $out.= $1,"\n";
      }
      $out.= substr $_, pos;

      
      >   
      > hab's nicht ausprobiert. so in etwa koennte es aber funzen.  
      
      Das hätte mir gefallen, denn man könnte es schön variieren, aber klappt leider nicht.  
      Und der reguläre Ausdruck ist wohl schon etwas für Fortgeschrittene, denn \G  
      habe ich in Selfhtml nicht gefunden (nur in Perldoc), wobei mir die Bedeutung nicht klar ist (auch reg. Ausdrücke sind noch Neuland für mich).  
      Danke trotzdem  
      Danni
      
      1. gudn tach Danni!

        wenn du's aber alles von hand programmieren willst, waere ein vorschlag:

        $_ = $string;

        my $out = '';
        while(/\G(.{40}\S{0,10})/gc){
          $out.= $1,"\n";
        }
        $out.= substr $_, pos;

        
        > >   
        > > hab's nicht ausprobiert. so in etwa koennte es aber funzen.  
        > Das hätte mir gefallen, denn man könnte es schön variieren, aber klappt leider nicht.  
          
        naja, "klappt nicht", heisst ja nicht, dass man es noch zurechtbiegen koennte. in diesem fall z.b. war nur das komma hinter $1 falsch.  
          
        den regulaeren ausdruck kannst du evtl. noch so zurechtbiegen, dass der whitespace jeweils in die aktuelle (und nicht in die naechste zeile) verschoben wird:  
          
        ~~~perl
          
        my $out = '';  
        while(/\G(.{40}\S{0,10}\s?)/gc){  
          $out.= $1."\n";  
        }  
        $out.= substr $_, pos;
        

        Und der reguläre Ausdruck ist wohl schon etwas für Fortgeschrittene, denn \G
        habe ich in Selfhtml nicht gefunden (nur in Perldoc), wobei mir die Bedeutung nicht klar ist (auch reg. Ausdrücke sind noch Neuland für mich).

        ja in selfhtml steht dazu noch nichts. das wird in der naechsten version besser.
        die beiden von mir verlinkten dokumente waren ja aus dem perl-manual. dort steht, was \G bedeutet, und es sind auch ein paar beispiele vorhanden.
        \G matcht das ende des matches des vorigen durchlaufs (also an der stelle pos).

        prost
        seth

        1. Gruezi seth,
          ich versteh zwar nicht warum, aber es funktioniert super.
          Ich bin beeindruckt wie mächtig so ein regulärer Ausdruck ist!
          Danke
          Danni

          1. gudn tach Danni!

            ich versteh zwar nicht warum, aber es funktioniert super.

            ok.
            hast du dir mal die beispiele im manual angeschaut? hast du die verstanden?

            wesentlich ist ja eigentlich bloss die zeile
              while(/\G(.{40}\S{0,10}\s?)/gc)

            schauen wir also zunaechst eine abgespeckte variante davon an:
              $_ = 'foo1_foo2';
              $_=~/(foo.)/;

            diese zeile prueft, ob der string $_ den string "foo." enthaelt, wobei der punkt ein beliebiges zeichen darstellt, und speichert der klammern wegen ggf. den gematchten teilstring in $1 ab. (siehe perldoc perlre und dort nach "$1" suchen).

            das laesst sich nach perl-art verkuerzen zu
              /(foo.)/;

            wird nun $1 ausgegeben, erhaelt man "foo1";

            was passiert aber wenn man noch mal /(foo.)/; ausfuehrt?
            beispiel:
              ~~~perl $_ = 'foo1_foo2';
              print $1,"\n" if /(foo.)/; # prints "foo1"
              print $1,"\n" if /(foo.)/; # prints "foo1"

            denn nach jeder regexp-anwendung, wird ein interner zeiger auf die position des gematchten strings zurueckgesetzt...  
            ...es sei denn, man setzt den g-modifier. das obige beispiel aendert sich dadurch wie folgt:  
              ~~~perl
            $_ = 'foo1_foo2';  
              print $1,"\n" if /(foo.)/g; # prints "foo1"  
              print $1,"\n" if /(foo.)/g; # prints "foo2"
            

            denn beim zweiten aufruf von /(foo.)/g; wird nicht ganz vorne in $_ versucht, eine entsprechung zu finden, sondern erst ab dem ende des letzten gematchten teilstrings. die position des zeigers kann man mittels pos abfragen:
              ~~~perl $_ = 'foo1_foo2';
              print $1,"\n" if /(foo.)/g; # prints "foo1"
              print pos,"\n";             # prints 4
              print $1,"\n" if /(foo.)/g; # prints "foo2"
              print pos,"\n";             # prints 9

            (ohne g-modifier ist pos undefined)  
              
            der g-modifier verhindert allerdings kein zuruecksetzen, falls ein matchen fehlschlaegt. dazu wieder ein beispiel:  
              ~~~perl
            $_ = 'foo1_foo2';  
              print $1,"\n" if /(foo1)/g;    # prints "foo1"  
              print pos,"\n" if defined pos; # prints 4  
              print $1,"\n" if /(foo1)/g;    # setzt den zeiger zurueck  
              print pos,"\n" if defined pos; # tut nix
            

            der c-modifier verhindert das zuruecksetzen im falle des nicht-matchens
              ~~~perl $_ = 'foo1_foo2';
              print $1,"\n" if /(foo1)/gc;   # prints "foo1"
              print pos,"\n" if defined pos; # prints 4
              print $1,"\n" if /(foo1)/gc;   # tut nix
              print pos,"\n" if defined pos; # prints 4

              
            so, jetzt fehlt bloss noch \G. das \G symbolisiert die stelle, an welcher der zeiger zuletzt war, also pos. moechte man, dass die foo.-teilstrings direkt hintereinanderstehen, ohne dass was dazwischen steht (wie in diesem fall der underscore "\_"), dann kann man mit \G quasi einen anker werfen.  
            dazu wieder ein beispiel:  
              ~~~perl
            $_ = 'foo1_foo2';  
              print $1,"\n" if /\G(foo.)/gc;  # prints "foo1"  
              print pos,"\n" if defined pos;  # prints 4  
              print $1,"\n" if /\G(foo.)/gc;  # tut nix, denn "\Gfoo." matcht "_foo2" nicht.  
              print pos,"\n" if defined pos;  # prints 4  
              print $1,"\n" if /\G_(foo.)/gc; # prints "foo2"  
              print pos,"\n" if defined pos;  # prints 9
            

            vielleicht ist jetzt auch verstaendlicher, was perldoc mit "The \G  assertion can be used to chain global matches" meint.

            so, jetzt alles klar? falls nicht frag, falls doch, sag, dass alles klar ist. wehe, du antwortest aber gar nicht! ;-)

            prost
            seth

            1. Hi,

              so, jetzt alles klar? falls nicht frag, falls doch, sag, dass alles klar ist. wehe, du antwortest aber gar nicht! ;-)

              Ich antworte sicherheitshalber gleich - bevor ich mich schlagen lasse.
              Das ganze muss ich in Ruhe nachvollziehen. Ich melde mich wieder, entweder mit Begeisterung, dass ich es gecheckt habe oder aber mit weiteren Fragen.
              Hoffentlich ist der Thread bis dahin noch nicht im Archiv gelandet.
              Gruss
              Danni

              1. gudn tach Danni!

                Ich antworte sicherheitshalber gleich - bevor ich mich schlagen lasse.

                ok, dann pfeif ich tony wieder zurueck.

                Das ganze muss ich in Ruhe nachvollziehen. Ich melde mich wieder, entweder mit Begeisterung, dass ich es gecheckt habe oder aber mit weiteren Fragen.

                brav!

                Hoffentlich ist der Thread bis dahin noch nicht im Archiv gelandet.

                falls er dann bereits archiviert sein sollte, darfst du gerne einen neuen thread beginnen und dort den archivierten verlinken.
                (gevierteil^Wfreundlich hinweisen wirst du bloss, wenn der kram noch nicht im archiv ist.)

                prost
                seth

                1. Hi seth,
                  hab's kapiert, super erklärt!
                  Danke
                  Danni