PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Zeichenkette finden und löschen bzw. ersetzen


Andi011
19.01.2007, 19:40
Hallo!

Habe bisher nur seeehr begrenzte Erfahrung mit regex und das nachfolgende Problem:

Ich möchte aus einer Text-Datei eine Zeichenfolge entfernen, die den jeweiligen Anfang und das Ende des herauszufilternden Textes (mit den dazwischen befindlichen Zeichenfolgen) begrenzt.

Bsp:

###herauszufilternder Text mit ziffern und zeichen##### beliebiger Text, bestehend aus einer unbekannten anzahl an ziffern und zeichen ###herauszufilternder Text mit ziffern und zeichen#####beliebiger Text, bestehend aus einer unbekannten anzahl an ziffern und zeichen###herauszufilternder Text mit ziffern und zeichen##### usw...

Ich habs mit mehreren Text-Editoren bzw. Filtern versucht, m. E. kann es mit sed gehen. Jedoch liefert mir mein Pattern nicht das gewünschte Ergebnis:

CODE_START=###
CODE_END=#####
sed -n 's/['$CODE_END'.*?'$CODE_START']/\n/gp'

Trotz google und langem probieren und verändern des pattern komme ich nicht auf einen grünen Zweig mit dem Ausdruck. Vielleicht kann mir hier jemand helfen...

Gruß

Andreas


TheFox
19.01.2007, 19:56
Vielleicht hilf dir das:

Regex in wiki (http://de.wikipedia.org/wiki/Regul%C3%A4rer_Ausdruck)

oder versuch es mal mit dem Pattern:
/[#]{3}([\w ]*)[#]{4}/i

kill4h`
19.01.2007, 20:27
Machst du das unter Linux?
Dann hier mein Vorschlag in Perl:
$str =~ m/#{3}([a-z0-9]+)#{4}[a-z0-9]*/i;
Da sollte dann das Ergebnis in $1 stehen.

Andi011
20.01.2007, 11:04
Machst du das unter Linux?
Dann hier mein Vorschlag in Perl:
$str =~ m/#{3}([a-z0-9]+)#{4}[a-z0-9]*/i;Da sollte dann das Ergebnis in $1 stehen.

Vielen Dank für die schnellen Antworten!

Ja mache das unter Linux, debian. Hatte ich vergessen zu sagen. Zudem sind die Trennzeichen für den herauszufilternden Text user-spezifisch, heißt anpassbar. Daher die Variablen $CODE_START und $CODE_END.
Das Ergebnis in der Ausgabe soll dann möglichst so aussehen:

herauszufilternder Text mit ziffern und zeichen
herauszufilternder Text mit ziffern und zeichen
herauszufilternder Text mit ziffern und zeichen
...


Soll auf der bash laufen, werde mal deinen Vorschlag mit perl ausprobieren!


Gruß

Andreas

Andi011
20.01.2007, 14:45
Machst du das unter Linux?
Dann hier mein Vorschlag in Perl:
$str =~ m/#{3}([a-z0-9]+)#{4}[a-z0-9]*/i;Da sollte dann das Ergebnis in $1 stehen.

Habs versucht:

#/usr/bin/perl
$str='###Teststring####blabla.:+*#;###Teststring2####jheshdaliew'-*:;###Teststring3;####';
$str =~ m/#{3}([a-z0-9]+)#{4}[a-z0-9]*/i;
print $1;
Funktioniert vom Prinzip auch, jedoch nicht, wenn der Text ein Simikolon enthält. Zudem müsste das ganze global arbeiten, also mehrfach "matchen". Da ich mit perl noch keine Erfahrung habe, versuchte ich mit print $2;
print $3; an die anderen Teststrings heranzukommen, leider ohne Erfolg.

Zumindest hat es vom Prinzip her gut funktioniert...


Gruß

Andreas

kill4h`
20.01.2007, 15:00
Das mit dem Semikolon kann ich mir gerade nicht erklären...
Eine globale Suche erreichst du mit dem Modifier 'g', also am Ende anstatt nur 'i' ein 'gi'.

Andi011
20.01.2007, 15:14
Das mit dem Semikolon kann ich mir gerade nicht erklären...
Eine globale Suche erreichst du mit dem Modifier 'g', also am Ende anstatt nur 'i' ein 'gi'.

Bin mit dem Simikolon auch ein Stück weiter. In Perl funktioniert mein regex von oben:

$CODE_START ='###';
$CODE_END ='####';
$str ='###Teststring;1;154####blabla;:-?hgk###Teststring;2;765####';
$str =~ m/$CODE_START(.*?)$CODE_END/g;
print $1;
print $2;liefert: "Teststring;1;154". Leider noch nicht "Teststring;2;765", obwohl global gesetzt.

Gruß

Andreas

kill4h`
20.01.2007, 15:25
Ich habe gerade nochmal nachgeschlagen und laut Kamelbuch sollte das in einem while() Konstrukt klappen.
Der Beispielcode dort ist:
$burglar = "Bilbo Baggins";
while($burglar =~ /b/gi){
printf "Ein B an %d gefunden\n", pos($burglar) -1;
}
Die Ausgabe ist dazu:
Ein B an 0 gefunden
Ein B an 3 gefunden
Ein B an 6 gefundenMit der Schleife und dem Modifier g sollte das Progressive Matching also funktionieren.

EDIT:
Hab grade noch was besseres gefunden:
Du kannst die Treffer auch einer Liste zuweisen:
@liste = /.../igm;
vorausgesetzt, dein String ist in $_. Aber auch das hier sollte klappen:
@liste = ($str =~ /.../igm);

HTH

Andi011
20.01.2007, 15:31
Ich habe gerade nochmal nachgeschlagen und laut Kamelbuch sollte das in einem while() Konstrukt klappen.
Der Beispielcode dort ist:
$burglar = "Bilbo Baggins";
while($burglar =~ /b/gi){
printf "Ein B an %d gefunden\n", pos($burglar) -1;
}Die Ausgabe ist dazu:
Ein B an 0 gefunden
Ein B an 3 gefunden
Ein B an 6 gefundenMit der Schleife und dem Modifier g sollte das Progressive Matching also funktionieren.
Danke, werd das gleich mal probieren. Frag mich nur, warum sed mit dem Ausdruck nix anzufangen weiß :confused:. Aber wenns mit perl klappt, werd ich mich wohl mal in die Sprachen einlesen...

Vielen Dank erstmal!!!

Andi011
20.01.2007, 15:52
Funktioniert bestens!!!

Vielen Dank!