CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Regular Expressions:
Combining variables and constants

 



kencl
User

Oct 20, 2001, 6:21 PM

Post #1 of 4 (5356 views)
Combining variables and constants Can't Post

Hi Folks,

I need a hand combining a variable with a constant as the matching variable. The file I'm reading in with "FH" is simply a one to one conversion table. eg:
1:::yellow
10:::orange
111:::green

Code
my $ColourChoice = &DecodeColour(10); 

sub DecodeColour {
$code = shift;
open(FH, "<ColourConversion.txt");
while (defined($line = <FH>)) { # read file into memory 1 line at a time
next unless $line =~ m/^($code)(:::)/;
(undef, $colour) = split(/:::/, $line);
last;
}
close(FH);
return $colour
}

The above code seems to give good results, but I wanted to check to make sure that the way you join a variable "$code" and a string ":::" is by surrounding it with round brackets.

Thanks.

>> If you can't control it, improve it, correlate it or disseminate it with PERL, it doesn't exist!


mhx
Enthusiast

Oct 20, 2001, 11:52 PM

Post #2 of 4 (5353 views)
Re: Combining variables and constants [In reply to] Can't Post

You could, of course, do it this way, but I'd prefer a repetition quantifier in this case, because the brackets use to catch their content, which is rather boring because it's always three colons. Wink
My solution would have been something like:

Code
#!/bin/perl -w 
use strict;
use IO::File;

my $colour = DecodeColour( 10 );
print "Your choice: $colour\n";

sub DecodeColour {
my $code = shift;
my $file = new IO::File "ColourConversion.txt"
or die "can't open file: $!\n";

/^$code:{3}(\w+)/ && return $1 while <$file>;
}

-- Marcus


Code
s$$ab21b8d15c3d97bd6317286d$;$"=547269736;split'i',join$,,map{chr(($*+= 
($">>=1)&1?-hex:hex)+0140)}/./g;$"=chr$";s;.;\u$&;for@_[0,2];print"@_,"



kencl
User

Oct 23, 2001, 12:12 PM

Post #3 of 4 (5344 views)
Re: Combining variables and constants [In reply to] Can't Post

Thanks mhx. Nice piece of code there :)

I have a couple of questions about it.

1) Why add the overhead of loading IO::File when I can just use open? My application is fairly memory intensive as it is so I need to avoid overhead as much as possible.

2) How does Perl know that the colon following the string variable isn't part of the variable name? Put another way, how does it know to interpolate the value of $code and not $code:?

3) I simplified the example conversion file for the purpose of asking my main question. However, in reality, the values following the 3 colons could be a string which includes spaces, special characters etc. For example, it could look like:

mycomment:::Perl's an awesome language!
myemail:::me@me.com
mycode::::this string begins with a colon. See the fourth colon over there? Isn't it pretty :)

So, I was wondering if I should modify the regex to:

Code
/^$code:{3}(\w+)$/  # added a $ to the end

Also note that I don't want the trailing carriage return, which I don't get when I use split().

Talk with ya later.

>> If you can't control it, improve it, correlate it or disseminate it with PERL, it doesn't exist!


mhx
Enthusiast

Oct 23, 2001, 10:24 PM

Post #4 of 4 (5340 views)
Re: Combining variables and constants [In reply to] Can't Post


In Reply To
1) Why add the overhead of loading IO::File when I can just use open? My application is fairly memory intensive as it is so I need to avoid overhead as much as possible.

I don't think it'll introduce too much overhead. However, you could use open as well.

In Reply To
2) How does Perl know that the colon following the string variable isn't part of the variable name? Put another way, how does it know to interpolate the value of $code and not $code:?

In Perl, the colon isn't a valid character for an identifier. So Perl will always stop before the colon and use only $code. However, there's a problem if two colons follow a variable name, because then the name of the variable is treated as a namespace:

Code
#!/bin/perl -w 
package code;
$test = 'Hello';
package main;
$code = 'Test';
print "$code::test\n";

This will print "Hello" and complain about $code being used only once. To achieve the (expected?) result, one has to write the following instead of the above:

Code
print "${code}::test\n";

which will print "Test::test".
I'm not sure about what exactly happens inside the perl interpreter if you put three colons after the identifier, as in your case, but to me it looks like it tries to access a variable in another namespace with the empty string as identifier. But that's pure speculation. Wink

In Reply To
3) I simplified the example conversion file for the purpose of asking my main question. However, in reality, the values following the 3 colons could be a string which includes spaces, special characters etc. For example, it could look like:

mycomment:::Perl's an awesome language!
myemail:::me@me.com
mycode::::this string begins with a colon. See the fourth colon over there? Isn't it pretty :)

So, I was wondering if I should modify the regex to:

/^$code:{3}(\w+)$/ # added a $ to the end

It's even simpler. Just use the following regex:

Code
/^$code:{3}(.*)/


In Reply To
Also note that I don't want the trailing carriage return, which I don't get when I use split().

The regex shouldn't capture the carriage return. If it does, your text file is in a different format than the native text files on the machine running the script normally are. If you want to explicitly disallow carriage returns and line feeds, use the following regex:

Code
/^$code:{3}([^\r\n]*)/

This should get rid of all of them.

-- Marcus


Code
s$$ab21b8d15c3d97bd6317286d$;$"=547269736;split'i',join$,,map{chr(($*+= 
($">>=1)&1?-hex:hex)+0140)}/./g;$"=chr$";s;.;\u$&;for@_[0,2];print"@_,"


 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives