Re: Group list elements
Hi, Cris Charley posted me the following tip: I did this with the code below, but there are even better solutions in the attachment to this post. They are from MJD quiz of the week #6. However, they don't meet the requirement that only 2 numbers in sequence should be reported seperately :-) I mailed to you because for some reason I couldn't mail the group! Could you please post?!! #!/usr/bin/perl use strict; use warnings; my $kommalist ="-3,-2,-1,-5,-4,20,22,23,24,25,27,28,31,32,33,50"; my @nums = split /,/, $kommalist; my $i = 0; my @result; while ($i < @nums) { my $start_idx = $i; my $begin = $nums[$i]; 1 while (++$i < @nums && ++$begin == $nums[$i]); if ($i - $start_idx <= 2) { push @result, $nums[$_] for $start_idx .. $i-1; } else { push @result, "$nums[$start_idx]..$nums[$i-1]"; } } my $result = join ",", @result; print $result; ... Thanks to everyone else how help me. Götz -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
is it possiale to regex this
Hi! I am trying to figure out a way to remove the c pointers from the following: *ci = *ci * (1.0 + ((gi/(w * *ci)) * (gi/(w * *ci; so that it will end ou as the following: ci = ci * (1.0 + ((gi/(w * ci)) * (gi/(w * ci; I am converting a c program with perl. Thanks, Jerry -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: is it possiale to regex this
[EMAIL PROTECTED] (Jerry Preston) wrote: > I am trying to figure out a way to remove the c pointers from the > following: > > *ci = *ci * (1.0 + ((gi/(w * *ci)) * (gi/(w * *ci; > > so that it will end ou as the following: > > ci = ci * (1.0 + ((gi/(w * ci)) * (gi/(w * ci; Not really difficult, if you know a little about regex. Have a look at perldoc perlre. BTW, here are some ways (assume my $string = '*ci = *ci * (1.0 + ((gi/(w * *ci)) * (gi/(w * *ci': ) 1. Simplest: $string =~ s/\*ci/ci/g; It searches for a literal "*" followed by the two letters "ci" and replace it all with the letters "ci". The g modifier after the pattern tells perl to do replacements all over the string. 2. More elegant:$string =~ s/\*(?=ci)//g; This does a "look-ahead assertion", i.e. searches for a literal "*" followed by the string "ci" (without including the string in the match) and replace it with nothing. 3. Generalized: $string =~ s/\*(?=[a-z]+)//g; Here you can match *any* literal "*" in your program followed by a valid string (read below) and remove it. Please note that the [a-z]+ is just an example. I don't know C so i can't say what are valid strings for variables. If you want to include all alphanumerics plus "_" you say [a-zA-Z0-9_] which becomes simply \w, and so on. Again, read perldoc perlre. You may want to add checks for a space before the "*". Hope this is a good starting point. -- Zanardi2k3 -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Pattern Matching Operators
[EMAIL PROTECTED] (Prasad Karpur) wrote: > Is there a similar operator in Perl for ${variable##pattern} as there > is in korn shell. Not knowing korn shell, i'm not sure if this is what you want, but there is a Pattern Matching Operator in perl, and it is the "m//" operator. Look at perldoc perlop and search for the section named "Regexp Quote-Like Operator". -- Zanardi2k3 -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
RE: Pattern Matching Operators
>Is there a similar operator in Perl for ${variable##pattern} as there is in korn shell. As far as I can tell, no. However, from http://wwwcgi.rdg.ac.uk:8081/cgi-bin/cgiwrap/wsi14/poplog/man/1/ksh : ${parameter##word} Remove Largest Prefix Pattern. The word will be expanded to produce a pattern. The parameter expansion then will result in parameter, with the largest portion of the prefix matched by the pattern deleted. So $variable =~ s/^(pattern){1}//g; should be close in effect to the ksh $variable = ${variable##pattern}; (see http://www.perldoc.com/perl5.6/pod/perlre.html) In any case, it apears that ksh offers a limited capability of substring processing through 4 varieties of parameter expansion ( (prefix,suffix) by (smallest,largest) ). The ksh documentation says "pattern matching notation (see patmat), rather than regular expression notation, will be used to evaluate the patterns" but I can't find any relevant documentation of "patmat" and doubt if it covers more than a small part of the functionality provided by perl's regular expression facility. -tristram -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
testing for substrings
Hi, I have a perl regex to test if a file resides under a particular directory. The test looks like this: if ($filename =~ $directory) { # yes, this filename resides under directory } This is working for most cases. However, it fails is the directory contains a +. For example: $filename = 'ports/www/privoxy+ipv6/files/patch-src::addrlist.c'; $directory = "^/?" . 'ports/www/privoxy+ipv6' . "/"; if ($filename =~ $directory) { # yes, this filename resides under directory } Yes, I can escape the + in the directory name, but then I'd have to test for all special regex characters and escape them too. That sounds awfully complicated. ;) I think it might just be easier to do a straight comparison of the first N characters of the two strings where N = length of the directory name. Any suggestions? thanks -- Dan Langille : http://www.langille.org/ -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: testing for substrings
Dan Langille wrote: > > Hi, Hello, > I have a perl regex to test if a file resides under a particular > directory. The test looks like this: > > if ($filename =~ $directory) { ># yes, this filename resides under directory > } > > This is working for most cases. However, it fails is the directory > contains a +. For example: > > $filename = 'ports/www/privoxy+ipv6/files/patch-src::addrlist.c'; > $directory = "^/?" . 'ports/www/privoxy+ipv6' . "/"; > if ($filename =~ $directory) { ># yes, this filename resides under directory > } > > Yes, I can escape the + in the directory name, but then I'd have to > test for all special regex characters and escape them too. That > sounds awfully complicated. ;) > > I think it might just be easier to do a straight comparison of the > first N characters of the two strings where N = length of the > directory name. > > Any suggestions? You could use the index function: if ( index( $filename, $directory ) >= 0 ) { # yes, this filename resides under directory } perldoc -f index If you want to use a regular expression then you need the quotemeta escape sequence: my $filename = 'ports/www/privoxy+ipv6/files/patch-src::addrlist.c'; my $directory = qr(^/?\Qports/www/privoxy+ipv6/\E); if ( $filename =~ /$directory/ ) { # yes, this filename resides under directory } perldoc -f quotemeta perldoc perlre perldoc perlop John -- use Perl; program fulfillment -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Should loops return a value?
I think it's better to keep this discussion on the list because i suppose there are other interested people, too. So, I put Your mail and my comments below: [EMAIL PROTECTED] wrote: I was thinking over your idea this morning, in the context of Perl's automatic context handling. I was wondering if it might be a good idea to return a different value depending on the context the loop is assigned in. For example: $loopmax = for (@etc) {} @looparray = for (@etc) {} %loophash = for (@etc) {} I was thinking this would set $loopmax to the number of times the loop ran, @looparray to an array of the last values worked with in the loop (Similar to the operation of a sub, except for each iteration. 'return' should of course be available to set a particular value.), and $loophash would be a hash with the key being the index value ($_ for the iteration) and the value being the same value put in the array. This might be extremely good. I've also been thinking what the default returned values should be but that's hard imagine. I think there might be some problems with this, too. For example if You wrote: $value= foreach(1 .. 3){ retlast $scalar if $scalar == 3; } , You would get answer 3 but it's a bit ambiguous because You can not now what returned it. I think the default returns are not as controlled as returns via retnext and it'd get messy if it'd be possible to use both ways. Default returns make the constructs forcibly to act more or less like filter ie to return (defaultly at least) as many values as the loop spins. Without default returns it'd be more natural to make the constructs to just roll over returning values only when the programmer wants to - and by that way the performance wouldn't downgrade at all if returns aren't used. The default returns still are very interesting and You had very good ideas about them. I'm really not sure should they somehow be included in this or not. The tagging was also suggested and it sounded good - i don't still understand everything about it. We don't have this problem with If's because they already return default values automatically - and i think it's just the best possible way with them. In addition it's possible to return more values by retnexts. I suppose it's possible to return hashes from these constructs already (have You tried it with the script attached to my last mail before this?). Just return a pairs of scalars and put them to hash instead of array. If you wanted the 'last' return value in the loop you could always use $looparray[-1] (the last value in the list), or it might be useful to provide a special syntax for that value. (Since it would be extremely common, and the $looparray[-1] solution has performance implications, especially with long running loops.) Of course, the standard interpolation would work as well: @looparray = for (@etc) { return ( $val1, $val2 ); } would return an array of array references. (And a bigger argument for special syntax to return only one value...) There should be no problems to return array references now. The hash return value is the most interesting to me: it allows the creation of certain types of hash very easily. For instance, I have one subroutine in a module I've written with 6 arguments, which I put into a hash, like so: %note{value} = $_[0]; %note{lang} = $_[1]; %note{location} = $_[2]; %note{server} = $_[3]; %note{bank} = $_[4]; %note{bankurl} = $_[5]; With the above loop syntax, I could write: my @argvals = ( 'value', 'lang', 'location', 'server', 'bank', 'bankurl' ); %note = foreach (@argvals) {$_[$i++];}; You are right. This would be great. But if one value-pair should be excluded there'd be problems. That's why i think it might be better the way it's now: %note = foreach (@argvals) {retnext $_,$_[$i++];}; It's more to write, but also much more flexible. If You want to return only 4 value-pairs, You could alter the code just a little bit (i haven't tested these examples): %note = foreach (@argvals) {retnext $_,$_[$i++] if($i < 4);}; This (i believe) works now. It's hard to say which one is better because You have to write more now but have more control. Or could there be better ways than these? What do You think? ($i++ might be replaceable by $_ in the last, I'd have to check.) This is much better readability from my standpoint (especially considering in the actual subroutine I'd separate the two statements by half a page of class initization necessary before I can get to the arguments...), and it has the advantage that I can add and remove arguments quickly by just changing the array. Just thought I'd run this by you, as a way to extend your idea. Daniel T. Staal I've been so "hurry" that I have made just one script with the translator - the script that was included in the translator's attachment - so it's easily possible that You have more practical experience than i. I'll also test it more and look what Your ideas feels w
storing values non-globally
Hi all, Sorry about subject line, it's the best I could do. Two (somewhat realted) questions... I have several types of user input values I am storing in %history, similar to the way the shell maintains a history of previous command line commands. These are only used by a sub-routine, but they need to remain valid for the life of the program. I see no reason for them to be global, but if they live in a subroutine, they will be initialized each time. My current solution is to place the %history variable and its sub-routine inside a block. A second (related?) problem. I have a variable $READ_ONLY that is needed by some routines. Right now this is also a global value which has a default value, but then is modified by one sub-routine. I see no reason for this to be global, either. I'm thinking that it would be better to set up a sub-routine called "file_mode" and use it like an OO-method getter/setter. You call it with a value (file_mode("r") and it sets this value. You call it without any parameters and it returns the current value. Is this a valid alternative to global variables? -K -- Kevin Pfeiffer International University Bremen -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: storing values non-globally
On Oct 6, Kevin Pfeiffer said: >I have several types of user input values I am storing in %history, similar >to the way the shell maintains a history of previous command line commands. >These are only used by a sub-routine, but they need to remain valid for the >life of the program. I see no reason for them to be global, but if they >live in a subroutine, they will be initialized each time. > >My current solution is to place the %history variable and its sub-routine >inside a block. There's nothing wrong with that. { my $count; sub add { ++$count } sub count { $count } } Now add() and count() have access to the lexical $count, but nothing else does. >A second (related?) problem. I have a variable $READ_ONLY that is needed by >some routines. Right now this is also a global value which has a default >value, but then is modified by one sub-routine. I see no reason for this to >be global, either. > >I'm thinking that it would be better to set up a sub-routine called >"file_mode" and use it like an OO-method getter/setter. You call it with a >value (file_mode("r") and it sets this value. You call it without any >parameters and it returns the current value. Have it return the old value regardless, like select() does. { my $mode = 'r'; sub file_mode { my $old = $mode; $mode = shift if @_; return $old; } sub thingy { if ($mode eq 'r') { ... } else { ... } } } -- Jeff "japhy" Pinyan [EMAIL PROTECTED] http://www.pobox.com/~japhy/ RPI Acacia brother #734 http://www.perlmonks.org/ http://www.cpan.org/ what does y/// stand for? why, yansliterate of course. [ I'm looking for programming work. If you like my work, let me know. ] -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]