/ Forside / Teknologi / Udvikling / Perl / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Perl
#NavnPoint
bjarneA 141
poul_from 50
soccer 30
Nicknack 14
Tmpj 0
Regulært udtryk
Fra : FePe


Dato : 24-04-04 11:31

Jeg skal matche følgende (i et lille node-test-program):

s: C2(1/2) C2(1/2)
a: G3(1/4) C3(1/2)
t: E2(1/2) G4(1/8)
b: C2(1/64) A(1/1)

hvor [satb], C2 og tallet efter '/' i parentesen skal matches for sig i
hvert tilfælde. Indtil videre virker det kun, hvis der er én node pr.
linje. Det regulære udtryk, jeg bruger er:

/^([satb]): ([A-H][1-5])\(1\/([1-8]\d?)\)/

Hvis det laves om til

/^([satb]): (([A-H][1-5])\(1\/([1-8]\d?)\) )*$/

virker det ikke. Det skulle ellers gerne matche hvert 'C2(1/2) ' indtil
linjeskift. Hvordan kan det lykkes og bedst gøres, uden at formatet af
filen skal laves om?

Mvh. FePe.


 
 
Lars Balker Rasmusse~ (24-04-2004)
Kommentar
Fra : Lars Balker Rasmusse~


Dato : 24-04-04 11:33

FePe <fepe@SLETtiscali.dk> writes:
> Jeg skal matche følgende (i et lille node-test-program):
>
> s: C2(1/2) C2(1/2)
> a: G3(1/4) C3(1/2)
> t: E2(1/2) G4(1/8)
> b: C2(1/64) A(1/1)
>
> Hvis det laves om til
>
> /^([satb]): (([A-H][1-5])\(1\/([1-8]\d?)\) )*$/
>
> virker det ikke. Det skulle ellers gerne matche hvert 'C2(1/2) ' indtil
> linjeskift. Hvordan kan det lykkes og bedst gøres, uden at formatet af
> filen skal laves om?

Men linien slutter jo ikke med " ", så du kan jo ikke matche på
mellemrummet. Prøv med

/^([satb]): (([A-H][1-5])\(1\/([1-8]\d?)\) ?)*$/

i stedet.
--
Lars Balker Rasmussen Consult::Perl
http://consult-perl.dk

FePe (24-04-2004)
Kommentar
Fra : FePe


Dato : 24-04-04 11:46

Lars Balker Rasmussen <lars@balker.org> writes:

> Men linien slutter jo ikke med " ", så du kan jo ikke matche på
> mellemrummet. Prøv med
>
> /^([satb]): (([A-H][1-5])\(1\/([1-8]\d?)\) ?)*$/
>
> i stedet.
> --
> Lars Balker Rasmussen Consult::Perl
> http://consult-perl.dk

Det virker desværre ikke helt, men bedre alligevel. Denne kode

while (<NOTEFILE>)
{
print;
if (/^([satb]): (([A-H][1-5])\(1\/([1-8]\d?)\) ?)*$/)
{
print "1: $1, 2: $2, 3: $3, 4: $4\n";
}
}

giver

$ ./music_analyser.pl
s: C2(1/2) C2(1/2)
1: s, 2: C2(1/2), 3: C2, 4: 2
a: C2(1/4) C2(1/2)
1: a, 2: C2(1/2), 3: C2, 4: 2
t: C2(1/2) C2(1/2)
1: t, 2: C2(1/2), 3: C2, 4: 2
b: C2(1/2) C2(1/2)
1: b, 2: C2(1/2), 3: C2, 4: 2

Men tak for det hurtige svar...

Mvh. FePe.



Lars Balker Rasmusse~ (24-04-2004)
Kommentar
Fra : Lars Balker Rasmusse~


Dato : 24-04-04 13:35

FePe <fepe@SLETtiscali.dk> writes:
> Lars Balker Rasmussen <lars@balker.org> writes:
>
>> Men linien slutter jo ikke med " ", så du kan jo ikke matche på
>> mellemrummet. Prøv med
>>
>> /^([satb]): (([A-H][1-5])\(1\/([1-8]\d?)\) ?)*$/
>>
>> i stedet.
>
> Det virker desværre ikke helt, men bedre alligevel. Denne kode

For bedre kontrol, så del problemet op:

while (<DATA>) {
print;
if (/^([satb]): (.*)/) {
my ($satb, $notes) = ($1, $2);
print " $satb\n";

while ($notes =~ /([A-H][1-5])\(1\/(\d\d?)\) ?/g) {
my ($node, $takt) = ($1, $2);
print "\t$1 $2\n";
}
}
}
__DATA__
s: C2(1/2) C2(1/2)
a: G3(1/4) C3(1/2)
t: E2(1/2) G4(1/8)
b: C2(1/64) A(1/1)

--
Lars Balker Rasmussen Consult::Perl
http://consult-perl.dk

René Larsen (24-04-2004)
Kommentar
Fra : René Larsen


Dato : 24-04-04 13:56

In article <408A41DA.7A93FC25@SLETtiscali.dk>, FePe wrote:
>
> Jeg skal matche følgende (i et lille node-test-program):
>
> s: C2(1/2) C2(1/2)
> a: G3(1/4) C3(1/2)
> t: E2(1/2) G4(1/8)
> b: C2(1/64) A(1/1)
>
> hvor [satb], C2 og tallet efter '/' i parentesen skal matches for sig i
> hvert tilfælde. Indtil videre virker det kun, hvis der er én node pr.
> linje. Det regulære udtryk, jeg bruger er:
>
> /^([satb]): ([A-H][1-5])\(1\/([1-8]\d?)\)/

Dette regulære udtryk vil i hvert fald *ikke* finde den sidste node
"A(1/1)".

> Hvis det laves om til
>
> /^([satb]): (([A-H][1-5])\(1\/([1-8]\d?)\) )*$/
>
> virker det ikke. Det skulle ellers gerne matche hvert 'C2(1/2) ' indtil
> linjeskift. Hvordan kan det lykkes og bedst gøres, uden at formatet af
> filen skal laves om?

Det ser ud som om det ikke er så nemt med et enkelt regulært udtryk. Det
kan dog gøres på denne måde, og den virker, uanset antallet af noder på
en linje:

<testprogram os="Win98SE" perl="ActiveState Perl v5.6.1">
while (<DATA>) {
chomp;
print "Linje: '$_'\n";
@a=();
if (m/^([satb]):/g) {
push @a, $1;
while (m/\G\s([A-H][1-5]?)\(1\/([1-8]\d?)\)/g) {
push @a, $1, $2;
}
}
print '@a=(' . join(', ', @a) . ")\n";
}
__DATA__
s: C2(1/2) C2(1/2)
a: G3(1/4) C3(1/2)
t: E2(1/2) G4(1/8)
b: C2(1/64) A(1/1)
</testprogram>

<uddata>
Linje: 's: C2(1/2) C2(1/2)'
@a=(s, C2, 2, C2, 2)
Linje: 'a: G3(1/4) C3(1/2)'
@a=(a, G3, 4, C3, 2)
Linje: 't: E2(1/2) G4(1/8)'
@a=(t, E2, 2, G4, 8)
Linje: 'b: C2(1/64) A(1/1)'
@a=(b, C2, 64, A, 1)
</uddata>

Jeg håber, det hjælper dig lidt.

MVH, René


FePe (25-04-2004)
Kommentar
Fra : FePe


Dato : 25-04-04 13:30

"René Larsen" wrote:

> Jeg håber, det hjælper dig lidt.

Det gør det helt klart. Tak for hjælpen til begge!

Mvh. FePe.



Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408914
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste