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

Spezielles Regex

Tags: Ähnliche Threads

Leser: 2


<< >> 5 Einträge, 1 Seite
tecker
 2008-11-11 11:39
#116174 #116174
User since
2008-02-26
77 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hi Leute,

ich müsste eine bestimmtes Verzeichnis rekursiv durchsuchen und in jeder Datei schauen ob das pattern "paragraph{ Text }" vorkommt und ggf. löschen OHNE den in den Klammern enthalten Text zu löschen. Also aus

Code: (dl )
1
2
3
Text vor Paragraph, paragraph{ Text in Paragraph}, Text dahinter.
Nochmal mit Paragraph, paragraph{ aber diesmal die schließende Klammer in der nächsten Zeile
.}


Soll werden:

Code: (dl )
1
2
3
Text vor Paragraph, Text in Paragraph, Text dahinter.
Nochmal mit Paragraph, aber diesmal die schließende Klammer in der nächsten Zeile
.



Mein Skript funktioniert erstmal soweit bis auf die Tatsache (wie schon angedeutet), dass die schließende Klammer vom Paragraph BLock auch in der nächsten und übernächsten Zeile vorkommen kann. Ich suche allerdings mit $_ diese ja in der gleichen Zeile. Wie kann ich mein Skript ändern so dass nach dem Auffinden des Patterns "paragraph{" bis zur nächsten schließenden Klammer gesucht wird und diese dann gelöscht wird?
Es können auch Blöcke mit geschweiften Klammern vorkommen die nicht paragraph{} sind und demnach nicht gelöscht werden dürfen bzw kann ein paragraph{} Block auch mehrmals in einem File auftauchen.


Hier mein Skript:

Code (perl): (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
41
42
43
44
45
46
47
48
49
50
51
52
#!/usr/bin/perl

use strict;
use warnings;
use File::Find;

my @files;
my @newcontent;
my $muster = '';


find(\&wanted, "/opt/test");


sub wanted
{
        if ( $File::Find::name =~ /$muster/)
        {
                print "gefunden .... $File::Find::name \n";
                push(@files,$File::Find::name);
        }
        return;
}


foreach my $file (@files)
{
        next if (-d $file);
        print "Oeffne File .... $file \n";
        open(FILE,"<$file") or die "Cant open $file $! \n";
        while (<FILE>)

        {
                if($_ =~ /paragraph\{/)
                {
                        $_ =~ s/paragraph\{//g;
                        $_ =~ s/\}//g;
                        push (@newcontent,$_);
                }
                else
                {
                push(@newcontent, $_);
                }
        }
        close(FILE);

        open(FH,">$file") or die "cant open $file $! \n";
        print FH @newcontent;
        close(FH);
        @newcontent = ();

}




Danke vorab.

VG
renee
 2008-11-11 12:00
#116175 #116175
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Sind die Dateien groß? Wenn sie nicht so übermäßig groß sind, dann kannst Du es so machen:

Code (perl): (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
41
#!/usr/bin/perl

use strict;
use warnings;
use File::Find;

my @files;
my $muster = '';


find(\&wanted, "paragraph");


sub wanted
{
        if ( $File::Find::name =~ /$muster/)
        {
                print "gefunden .... $File::Find::name \n";
                push(@files,$File::Find::name);
        }
        return;
}


foreach my $file (@files)
{
        next if (-d $file);
        my $newcontent;
        print "Oeffne File .... $file \n";
        open(FILE,"<$file") or die "Cant open $file $! \n";
        {
           local $/;
           $newcontent = <FILE>;
           $newcontent =~ s!paragraph\{(.*?)\}!$1!sg;
        }
        close FILE;
        open(FH,">$file") or die "cant open $file $! \n";
        print FH $newcontent;
        close(FH);

}
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
tecker
 2008-11-11 12:25
#116176 #116176
User since
2008-02-26
77 Artikel
BenutzerIn
[Homepage] [default_avatar]
Ok funktioniert. Danke! Sind viele kleine Dateien (ca. 2000), aber hat keine 10 Sekunden gedauert ;-)

2 Fragen dazu:

1. Warum muss ich hier lokal einen Rekord-Trenner definieren? Was bewirkt diese Zeile?

2. $newcontent =~ s!paragraph\{(.*?)\}!$1!sg;

Etwas schwer nachzuvollziehen diese Zeile. Warum Ausrufezeichen statt Backslash? (.*?) captured beliebige Zeichen zwischen "paragraph{" und "}" aber das was danach steht ist mir im Moment noch fremd.

Viele Grüße
renee
 2008-11-11 12:47
#116179 #116179
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Zu 1.)

Durch local $/ ist der Trenner undef, wodurch die ganze Datei auf einmal eingelesen wird. Dadurch muss ich mich nicht durch das Array durcharbeiten.

Mehr zu $/ findest Du hier:

perldoc perlvar
http://reneeb-perlblog.blogspot.com/2007/10/ntzlic...

Zu 2.) Bei s/// kann man beliebige Trenner nehmen. Ich habe mir irgendwann angewöhnt, Ausrufezeichen zu nehmen. Du kannst es auch durch s/paragraph\{(.*?)\}/$1/sg; ersetzen. Die Zeichen, die durch das (.*?) gespeichert wurden, stehen hier in $1 (mehr zu $<number> in perldoc perlvar). Da ich "paragraph{<beliebige Zeichen>}" durch "<beliebige Zeichen>" ersetze, ist das "paragraph{" und das "}" weg.

s und g sind modifier des Regulären Ausdrucks. "s" bedeutet "single line". Dadurch matcht "." auch auf Newlines.

Vergleiche:

Code (perl): (dl )
1
2
3
"test\n123" =~ /test.123/ and print "matched";
# vs.
"test\n123" =~ /test.123/s and print "matched (2)";


"g" bedeutet "global matching". Dadurch werden "alle" Vorkommen ersetzt. Ohne das "g" würde nur das erste Vorkommen ersetzt werden.

Vergleiche:

Code (perl): (dl )
1
2
3
4
5
6
my $var = "test\n123";
$var =~ s!t!!;
print $var,"\n";
$var = "test\n123";
$var =~ s!t!!g;
print $var,"\n";


Siehe auch http://perldoc.perl.org/perlre.html#Modifiers
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
tecker
 2008-11-11 16:42
#116195 #116195
User since
2008-02-26
77 Artikel
BenutzerIn
[Homepage] [default_avatar]
Wieder etwas schlauer geworden ;)
<< >> 5 Einträge, 1 Seite



View all threads created 2008-11-11 11:39.