Suchen+Ersetzen+Addieren

Suchen+Ersetzen+Addieren

am 23.06.2006 12:27:03 von Klaus Boer

Hallo,
bin Perl-Anfaenger und versuche folgendes mit RegExp zu machen:

1) Oeffnen einer Textdatei (Index) mit Seitenzahlen.
2) Alle Ziffern (3-stellig) sollen um 2 erhoeht werden.
3) Datei wird neu geschrieben.

Habe es so versucht:

use strict;
my $zeichen1;
my $ziffer2;
my $ziffer3;
my $ziffer3neu;
my $zeichen4;

open(OUT, ">RegisterOut.txt") or die " Die Datei kann nicht geoeffnet
werden: $!\n";
open(FILE, "RegisterIn.txt") or die " Die Datei kann nicht geoeffnet
werden: $!\n";

while () {

if (/([^0-9])([1-9][0-9])([0-9])([^0-9])/){
$zeichen1=$1;
$ziffer2=$2;
$ziffer3=$3;
$ziffer3neu=$ziffer3+2;
$zeichen4=$4;
s//$zeichen1$ziffer2$ziffer3neu$zeichen4/;

}

print OUT;

}

close OUT;
close FILE;

Leider wird nur die erste gefundene 3-stellige Ziffer um 2 erhöht.
Was mach ich da falsch?

Bin dankbar für jeden Hinweis
Klaus

Re: Suchen+Ersetzen+Addieren

am 23.06.2006 12:38:32 von Mirco Wahab

Thus spoke Klaus Boer (on 2006-06-23 12:27):

> 1) Oeffnen einer Textdatei (Index) mit Seitenzahlen.
> 2) Alle Ziffern (3-stellig) sollen um 2 erhoeht werden.
> 3) Datei wird neu geschrieben.

_NUR_ die 3-stelligen \d{3} um 2 erhöhen:

....
while() {
s/(? print OUT;
}
....

Viele Grüße

Mirco

Re: Suchen+Ersetzen+Addieren

am 23.06.2006 12:43:31 von Mirco Wahab

Thus spoke Mirco Wahab (on 2006-06-23 12:38):

> Thus spoke Klaus Boer (on 2006-06-23 12:27):
>> 1) Oeffnen einer Textdatei (Index) mit Seitenzahlen.
>> 2) Alle Ziffern (3-stellig) sollen um 2 erhoeht werden.
>> 3) Datei wird neu geschrieben.
>
> _NUR_ die 3-stelligen \d{3} um 2 erhöhen:
>

Uups, sorry, Du wolltest ja _JEDE_ ZIFFER erhöhen ;-)


while() {
s/(? print;
}


Viele Grüße

Mirco

Re: Suchen+Ersetzen+Addieren

am 23.06.2006 15:05:39 von Klaus Boer

Vielen Dank, Mirco,
was ich allerdings als Anfaenger nicht verstehe, ist:
?
Ausrufungszeichen bedeutet doch Negation -oder?. Warum nicht [^\d]
Und wieso ?<
Das verstehe ich nicht.

Kannst du mir das kurz auf Neudeutsch übersetzen

Vielen Dank
Klaus

Re: Suchen+Ersetzen+Addieren

am 23.06.2006 15:28:42 von Mirco Wahab

Thus spoke Klaus Boer (on 2006-06-23 15:05):

> was ich allerdings als Anfaenger nicht verstehe, ist:
> ? >
> Ausrufungszeichen bedeutet doch Negation -oder?. Warum nicht [^\d]
> Und wieso ?<
> Das verstehe ich nicht.
>
> Kannst du mir das kurz auf Neudeutsch übersetzen

Hallo Klaus,

die korrekte Expression für Deinen Fall
lautet:

...
s/(? ...

die Zeichenklassen [\d] sind also garnicht nötig.

Was heisst das nun alles? Das lässt sich auch
übersichtlicher schreiben, wenn man für die
Regex den /x - "Übersichtlichkeits-Modifizierer"
verwendet:

while() {
s{ # ==> substituiere Ausdruck
(? (\d{3}) # 3 x \d einfangen -> $1
(?!\d) # lookahead: wenn nicht \d anschliesst
}
{ # ==> mit folgendem Ausdruck
2 + $1 # Ausfuehren zur Laufzeit bei /e
}egx; # /e und /x - Modifizierer gesetzt

print OUT;
}

Die 3-stellige Zahl wird also als
Sequenz von \d{3}, also _genau_
3 x etwas zahlenartiges, verstanden

- es wird geschaut, ob vorher auch
_nicht_ eine Zahl steht
? das ist (negativer) "Lookbehind",
(dagegen würde ?<= \d fest-
stellen, _dass_ eine Zahl da steht)
(positiver Lookbehind)

- es wird geschaut, ob nachher auch
_nicht_ eine Zahl steht
?! \d
das ist (negativer) "Lookahead",
(dagegen würde ?= \d fest-
stellen, _dass_ eine Zahl da steht)
(positiver Lookahead)

- diese Lookaheads/Lookbehinds "schauen nur",
d.h. sie "fressen" keine Zeichen, das tut
nur die geklammerte Gruppe (\d{3}), welche
mann dann in $1 auf der rechten Seite der
Substitution wiederfindet - aber wenn der
lokk-'around' nicht erfüllt ist, wird auch
$1 nicht gematcht. So finden wir nur Zahlen,
die exakt 3 Stellen haben.

- hinter der Regex haben wir ein /e, d.h.
der Ausdruck auf der rechten Seite wird
"ausgeführt+eingesetzt" und nicht nur
"eingesetzt", wie ohne /e
ein
s/ (\d+) / sin($1 * Pi / 180) /e
würde einen Winkel (Grad) im Text durch
seinen Sinus-Wert ersetzen.

- wenn hinter der Regex ein /x steht,
dann muss man Leerzeichen explizit
angeben, kann aber dafür Leerzeichen
für die schönere "Formatierung" verwenden

Hoffe, ich habe alle Klarheiten
beseitigt ;-)

Viele Grüße

Mirco

Re: Suchen+Ersetzen+Addieren

am 23.06.2006 16:03:40 von Klaus Boer

Hallo Mirco,
das muss ich erst mal verdauen.
Ich danke dir vielmals für die schnelle und ausführliche Antwort.

Grüsse
Klaus

Mirco Wahab schrieb:
> Thus spoke Klaus Boer (on 2006-06-23 15:05):
>
>> was ich allerdings als Anfaenger nicht verstehe, ist:
>> ? >>
>> Ausrufungszeichen bedeutet doch Negation -oder?. Warum nicht [^\d]
>> Und wieso ?<
>> Das verstehe ich nicht.
>>
>> Kannst du mir das kurz auf Neudeutsch übersetzen
>
> Hallo Klaus,
>
> die korrekte Expression für Deinen Fall
> lautet:
>
> ...
> s/(? > ...
>
> die Zeichenklassen [\d] sind also garnicht nötig.
>
> Was heisst das nun alles? Das lässt sich auch
> übersichtlicher schreiben, wenn man für die
> Regex den /x - "Übersichtlichkeits-Modifizierer"
> verwendet:
>
> while() {
> s{ # ==> substituiere Ausdruck
> (? > (\d{3}) # 3 x \d einfangen -> $1
> (?!\d) # lookahead: wenn nicht \d anschliesst
> }
> { # ==> mit folgendem Ausdruck
> 2 + $1 # Ausfuehren zur Laufzeit bei /e
> }egx; # /e und /x - Modifizierer gesetzt
>
> print OUT;
> }
>
> Die 3-stellige Zahl wird also als
> Sequenz von \d{3}, also _genau_
> 3 x etwas zahlenartiges, verstanden
>
> - es wird geschaut, ob vorher auch
> _nicht_ eine Zahl steht
> ? > das ist (negativer) "Lookbehind",
> (dagegen würde ?<= \d fest-
> stellen, _dass_ eine Zahl da steht)
> (positiver Lookbehind)
>
> - es wird geschaut, ob nachher auch
> _nicht_ eine Zahl steht
> ?! \d
> das ist (negativer) "Lookahead",
> (dagegen würde ?= \d fest-
> stellen, _dass_ eine Zahl da steht)
> (positiver Lookahead)
>
> - diese Lookaheads/Lookbehinds "schauen nur",
> d.h. sie "fressen" keine Zeichen, das tut
> nur die geklammerte Gruppe (\d{3}), welche
> mann dann in $1 auf der rechten Seite der
> Substitution wiederfindet - aber wenn der
> lokk-'around' nicht erfüllt ist, wird auch
> $1 nicht gematcht. So finden wir nur Zahlen,
> die exakt 3 Stellen haben.
>
> - hinter der Regex haben wir ein /e, d.h.
> der Ausdruck auf der rechten Seite wird
> "ausgeführt+eingesetzt" und nicht nur
> "eingesetzt", wie ohne /e
> ein
> s/ (\d+) / sin($1 * Pi / 180) /e
> würde einen Winkel (Grad) im Text durch
> seinen Sinus-Wert ersetzen.
>
> - wenn hinter der Regex ein /x steht,
> dann muss man Leerzeichen explizit
> angeben, kann aber dafür Leerzeichen
> für die schönere "Formatierung" verwenden
>
> Hoffe, ich habe alle Klarheiten
> beseitigt ;-)
>
> Viele Grüße
>
> Mirco
>
>
>
>