Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]8159[/thread]

suchen / ersetzen >> nur 2. / 3. / 4. Treffer ?!?: suchen ersetzen Problem



<< >> 7 Einträge, 1 Seite
Gast Gast
 2006-07-11 18:24
#68048 #68048
Hallo zusammen,

versuche (schon viel zu lange; leider auch nichts im Internet oder im Forum gefunden) einen suchen/ersetzen Algorithmus ins Leben zu rufen:

BEISPIEL: Folgender String: "aasdf asdlfa dasf". Jetzt möchte ich mit Perl realisieren, dass er mir (auf Zuruf) das 2. oder 3. "a" durch einen anderen String ersetzt...

Ist bestimmt total simpel; ich stehe im Moment auf dem Schlauch...

VIelen Dank schon mal,

Christian
Linuxer
 2006-07-11 21:40
#68049 #68049
User since
2006-01-27
3870 Artikel
HausmeisterIn

user image
Hallo,
hier mein Vorschlag:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#!/usr/bin/perl
# vi:ts=4 sw=4 et:
use strict;
use warnings;

#> global variables
#> ----------------------------------------------------------------------------

use vars qw( $str $what $for $pos $last $cnt );

$str = 'aasdf asdlfa dasf'; # welcher string soll bearbeitet werden
$what = 'a'; # was suchen wir
$for = 'xxx'; # womit wollen wir es ersetzen
$pos = 2; # das wievielte auftauchen soll ersetzt werden


#> main script
#> ----------------------------------------------------------------------------

( $last, $cnt ) = ( 0, 0 ); # initialisiere counter

# solange wir das gesuchte finden
while ( $last > -1 ) {

# ermittle position(en) des gesuchten
$last = index($str, $what, $last);

# ende der schleife, wenn nix mehr gefunden;
# oder erhoehe den trefferzaehler
$last == -1 ? last : $cnt++;

# ersetze in $str das auftreten von $what mit $for
# wenn die gezaehlten treffer $cnt der gewuenschten anzahl $pos
# entsprechen
substr($str, $last, length($what), $for) if ( $cnt == $pos );

$last++;
}

print $str, $/;
meine Beiträge: I.d.R. alle Angaben ohne Gewähr und auf Linux abgestimmt!
Die Sprache heisst Perl, nicht PERL. - Bitte Crossposts als solche kenntlich machen!
betterworld
 2006-07-11 22:28
#68050 #68050
User since
2003-08-21
2613 Artikel
ModeratorIn

user image
Entweder so:
Code: (dl )
$text =~ s/a/$neu/ for 1,2,3;

Oder so:
Code: (dl )
1
2
my $count = 0;
$text =~ s/(a)/$count++ < 3 ? "xx" : $1/g;


Das erste hat den Nachteil, dass es nur funktioniert, wenn $neu nicht "a" enthält.

Effizienznachteile haben beide, je nach Verteilung der "a"s.

Dann habe ich noch einen (vielleicht?) effizienteren Vorschlag, der aber etwas hässlich aussieht:
Code: (dl )
1
2
3
4
5
my $count = 0;
while ($text =~ m{(a)}g) {
substr($text, $-[0], $+[0]-$-[0], "XX");
last if ++$count >= 3;
}


Nachtrag: So sollte es auch gehen:
Code: (dl )
1
2
3
4
5
6
7
8
9
my $count = 0;
my $text = 'aeuaeueauaeuau';
my $search = 'a';
my $replace = 'XX';
while ($text =~ m{\Q$search}g) {
substr($text, pos($text)-length($search), length($search), $replace);
last if ++$count >= 3;
}
print "$text\n";
\n\n

<!--EDIT|betterworld|1152643753-->
Unr33L
 2006-07-12 12:44
#68051 #68051
User since
2005-03-22
2 Artikel
BenutzerIn
[default_avatar]
Hallo,

habe Vorschlag 3 verwendet; funktioniert p e r f e k t !!!

Danke für die Antwort(en),

Christian
Crian
 2006-07-12 15:43
#68052 #68052
User since
2003-08-04
5866 Artikel
ModeratorIn
[Homepage]
user image
hmmm

zweites a ersetzen:
Code: (dl )
s~(?:^[^a]*a[^a]*)a~$1b~;


drittes a ersetzen:
Code: (dl )
s~(?:^[^a]*(?:a[^a]*){2}a~$1b~;
\n\n

<!--EDIT|Crian|1152704676-->
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
sid burn
 2006-07-12 16:41
#68053 #68053
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
Ich hatte es auch eher so Verstanden das du das zweite, oder dritte "a" ändern möchtest, und das was davor ist unberührt lassen.

Code: (dl )
1
2
3
if ( $text =~ m/(?:(a).*?){3}/ ) {
substr($text, $-[1], $+[1] - $-[1]) = '(aa)';
}

Ich würde das ganze so lösen. Ist etwas flexibler.
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
betterworld
 2006-07-12 18:03
#68054 #68054
User since
2003-08-21
2613 Artikel
ModeratorIn

user image
[quote=sid burn,12.07.2006, 14:41]Ich hatte es auch eher so Verstanden das du das zweite, oder dritte "a" ändern möchtest, und das was davor ist unberührt lassen.[/quote]
Oh, stimmt... Das hatte ich total falsch gelesen. Aber der OP schien ja trotzdem zufrieden zu sein.
<< >> 7 Einträge, 1 Seite



View all threads created 2006-07-11 18:24.