[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: notes regex expression
From: |
Jim Tisdall |
Subject: |
Re: notes regex expression |
Date: |
Tue, 12 Sep 2017 14:05:45 -0400 |
User-agent: |
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:52.0) Gecko/20100101 Thunderbird/52.3.0 |
I have been using a perl regular expression to parse lilypond notes for my own
application,
which handles guitar notes with possible right hand, left hand, plectrum,
string, glissando markings.
Thus it only includes some of the features of lilypond notes. It assumes
english note names
(easily modified).
$noteRE = '
(?<original>
(
(
(< # lilypond grouping
(?<pitch> # $-{pitch}[0]
(?<name> [a-g](ss*|ff*)?\b) #
$-{name}[0]
(?<octave> (,,*|\'\'*)?) #
$-{octave}[0]
)
(?<duration> (\d+\.*)?) #
$-{duration}[0]
(
((\\\(?<string> [1-6]))?) #
$-{string}[0]
|
(((-(?<LH> [0-4])) | none )?)
# $-{LH}[0]
|
(?<plectrum> \\\downbow|\\\upbow)
# $-{plectrum}[0]
|
(?<PIMA> -?\\\(RH|rightHandFinger)\
\#[0-4]\ ) # $-{PIMA}[0]
)*
>) # lilypond grouping
(
((\\\(?<glissando> glissando))?) #
$-{glissando}[0]
|
(?<duration> (\d+\.*)?) #
$-{duration}[1]
|
(?<other> ([\\^_\-]"\S")? | \S*) # other
arbitrary constructs
)*
)
|
(
( # without lilypond grouping
(?<pitch> # $-{pitch}[1]
(?<name> [a-g](ss*|ff*)?\b) #
$-{name}[1]
(?<octave> (,,*|\'\'*)?) #
$-{octave}[1]
)
(?<duration> (\d+\.*)?) #
$-{duration}[2]
(
((\\\(?<string> [1-6]))?) #
$-{string}[1]
|
(((-(?<LH> [0-4])) | none )?)
# $-{LH}[1]
|
(?<plectrum> \\\downbow|\\\upbow)
# $-{plectrum}[1]
|
(?<PIMA> -?\\\(RH|rightHandFinger)\
\#[0-4]\ ) # $-{PIMA}[1]
)*
) # without lilypond grouping
(
(?<duration> (\d+\.*)?) #
$-{duration}[3]
|
((\\\(?<glissando> glissando))?) #
$-{glissando}[1]
|
(?<other> ([\\^_\-]"\S")? | \S*) # other
arbitrary constructs
)*
)
)
|
(
(?<pitch> # $-{pitch}[2]
(?<name> [rR]) # $-{name}[2]
)
(?<duration> (\d+\.*)?) # $-{duration}[4]
)
)
';
I use the regular expression $noteRE in the following parse function which
creates a note object:
sub parsenote {
my($self, $lilynote) = @_;
# best used on new note: may reset e.g. duration
# if called on pitch of existing note
unless((defined $lilynote) and $lilynote) {
Error(Trace("Cannot parse note: input lilynote is not
defined"));
return 0;
}
# simple case of name and octave
if($lilynote =~ /^([ra-gA-G][sf]*)([,']*)$/) {
$self->set_type('note');
$self->set_pitch($lilynote);
$self->set_name($1);
$self->set_octave($2);
return(1);
}
$lilynote =~ /$noteRE/x or return 0;
$self->set_type('note');
if(defined $-{pitch}[0]) {
$self->set_pitch($-{pitch}[0]);
}elsif(defined $-{pitch}[1]) {
$self->set_pitch($-{pitch}[1]);
}elsif(defined $-{pitch}[2]) {
$self->set_pitch($-{pitch}[2]);
}
if(defined $-{name}[0]) {
$self->set_name($-{name}[0]);
}elsif(defined $-{name}[1]) {
$self->set_name($-{name}[1]);
}elsif(defined $-{name}[2]) {
$self->set_name($-{name}[2]);
}
if(defined $-{octave}[0]) {
$self->set_octave($-{octave}[0]);
}elsif(defined $-{octave}[1]) {
$self->set_octave($-{octave}[1]);
}
if(defined $-{duration}[0]) {
$self->set_duration($-{duration}[0]);
}elsif(defined $-{duration}[1]) {
$self->set_duration($-{duration}[1]);
}elsif(defined $-{duration}[2]) {
$self->set_duration($-{duration}[2]);
}elsif(defined $-{duration}[3]) {
$self->set_duration($-{duration}[3]);
}elsif(defined $-{duration}[4]) {
$self->set_duration($-{duration}[4]);
}
if(defined $-{string}[0]) {
$self->set_string($-{string}[0]);
}elsif(defined $-{string}[1]) {
$self->set_string($-{string}[1]);
}
if(defined $-{LH}[0]) {
$self->set_LH($-{LH}[0]);
}elsif(defined $-{LH}[1]) {
$self->set_LH($-{LH}[1]);
}
if(defined $-{PIMA}[0]) {
$self->set_PIMA($-{PIMA}[0]);
}elsif(defined $-{PIMA}[1]) {
$self->set_PIMA($-{PIMA}[1]);
}
if(defined $-{plectrum}[0]) {
$self->set_plectrum($-{plectrum}[0]);
}elsif(defined $-{plectrum}[1]) {
$self->set_plectrum($-{plectrum}[1]);
}
if((defined $-{glissando}[0]) and $-{glissando}[0]) {
my $j = "\\" . $-{glissando}[0];
$self->set_glissando( $j );
}elsif((defined $-{glissando}[1]) and $-{glissando}[1]) {
my $j = "\\" . $-{glissando}[1];
$self->set_glissando( $j );
}
if($lilynote eq $-{original}[0]) {
# do not actually reset original, so you can use this parse
# function to e.g. change the octave, without changing, say,
gliss
# $self->set_original($lilynote);
}else{
#die "parsenote: input $lilynote output ",$-{original}[0];
Error(Trace("Cannot parse input $lilynote : only found
",$-{original}[0]));
return 0;
}
# fret is used in computation but not present in note format
if( defined $self->get_string and $self->get_string and defined
$self->get_pitch and $self->get_pitch ) {
$self->set_fret(
$stringAndPitch2Fret[$self->get_string]{$self->get_pitch} );
}
return 1;
}