Text splitten
Danni
- perl
0 Texter mit x0 Danni
0 seth
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
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.
Hallo, muß es eine Perl-Lösung sein?
Ja, sonst ka i nex!
Ja, sonst ka i nex!
I ka ka Perl.
gudn tach!
ich suche eine "elegante" Möglichkeit, einen beliebigen Text nach folgenden Kriterien in Teiltexte aufzuteilen:
- 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.- 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
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
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
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
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
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
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
Hi seth,
hab's kapiert, super erklärt!
Danke
Danni