Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

PERL search function 1

Status
Not open for further replies.

NateBro

Programmer
Sep 1, 2004
233
US
ok, how would i search a var @lots_of_lines for a piece of data that starts with lets say <+0+> and ends with <-0->?

i know how to look for <+0+> and write that line, but i don't know how to write that line and all the other lines between the <+0+> <-0-> marks.

thank you for your time.
~Nate_Bro


this is how i get the one line...
Code:
@lots_of_lines;

for ($i = 0; $i <= $#lots_of_lines; $i++){
 if ($lots_of_lines[$i] =~ <+0+>){
 print "$lots_of_lines[$i]";
 }
}
 
I also have another problum with the find...


this code should check to see if $thing2 is null or eq nothing, and if it does print - or +. but its not, its printing..

## and also take out spaces if there are any.

&nbsp;<a href="javascript:" onclick="JavaScript:window.open(' color="#CCCCCC"></font></a>
&nbsp;<a href="javascript:" onclick="JavaScript:window.open(' ','profile','toolbar=0,location=0,status=0,menubar=0,scrollbars=1,resizable=1,width=590,height=425')"><font color="#CCCCCC"> </font></a>
&nbsp;<a href="javascript:" onclick="JavaScript:window.open(' Nate_Bro','profile','toolbar=0,location=0,status=0,menubar=0,scrollbars=1,resizable=1,width=590,height=425')"><font color="#CCCCCC"> Nate_Bro</font></a>
&nbsp;<a href="javascript:" onclick="JavaScript:window.open(' Crimson Mohawk','profile','toolbar=0,location=0,status=0,menubar=0,scrollbars=1,resizable=1,width=590,height=425')"><font color="#CCCCCC"> Crimson Mohawk</font></a>

Code:
for ($i = 0; $i <= $#users_online; $i++){

my $thing = "$users_online[$i]";
chomp($thing);
$thing = "$thing'";

my $thing2 = "$users_online[$i]";
chomp($thing2);
$thing2 = "$thing2</font></a>\n";

    my $space = " ";
    my $no_space = "";
    $thing2=~ s/\$space/$no_space/g;
    $thing =~ s/\$space/$no_space/g;
    my $nuller="null";
    
if ($thing eq $space){
print "+";
}
else if ($thing eq $no_space){
print "-";
}
else {
    if ($thing =~ /$nuller/){
    print "";
    }
    else {
    print "&nbsp;<a href=\"javascript:\" onclick=\"JavaScript:window.open('[URL unfurl="true"]http://s101571840.onlinehome.us/mss/cgi-bin/MB/register.cgi?rHy2=pro&name=$thing,'profile','toolbar=0,location=0,status=0,menubar=0,scrollbars=1,resizable=1,width=590,height=425')\"><font[/URL] color=\"#CCCCCC\">$thing2";
    }
    }
}

thanks again for your time :)
 
For your first question, is the pattern "<+0+>" or is it "+0+" ? The first character after =~ acts as the delimiter of the pattern, so you're only looking for the latter.

The logic is pretty much as you've layed out already. Check the list until your pattern matches. Then set a flag saying you've matched, and continute looping, this time looking for the closing pattern. Once that's found, unset your flag, and maybe start looking for the start again, if you're expecting a pattern to repeat. The data you're after is all the lines you looped over while the flag was set.

I'm not following what you're trying to do in your second post at all. As a casual observation, I'd strongly suggest looking into some kind of templating system instead of generating HTML from code. And I'd also strongly encourage you to never use a <FONT> tag again. ;-)

________________________________________
Andrew

I work for a gift card company!
 
sorry, my second was not explained very well, all i want to do is see if there are any spaces in the var $thing and if there are take them out.

i tried this.....
Code:
    my $space = " ";
    my $no_space = "";
    $thing =~ s/\$space/$no_space/g;
...but it didn't take out all the spaces, just one.

thanks so much for your time, i really appreciate it.

i'm really new to perl, so i'm very slow at it, and am not familiar with a lot of functions like FLAGS so I'll go read my book. thanks for pointing me in the right direction, i tried looking for a way to do it and now i know, thanks.
 
Pretty new to programming, too, I assume, as a flag is just a term for a binary variable you use to tell if something is on or off. Here's one perlish way:

Code:
my $flag = 0;
for(@lots_of_lines) {
    /<+0+>/ && $flag++;
    $flag && print && /<-0->/ && $flag--;
}

And the best way to take spaces out of $thing is =~ tr/ //

________________________________________
Andrew

I work for a gift card company!
 
TIMTOWDTI - using the range `..' operator:
Code:
/<\+0\+>/ .. /<-0->/ and print for ( @lots_of_lines );

In scalar context, the range operator returns false (i.e. nothing will print) until the first expression is true. In this case, it won't print anything until it finds <+0+> in the array. It will then continue to return true (i.e. lines will be printed) until the second expressions is true (i.e. until it matches <-0->) so it then stops printing.

If you're using icrf's code, you'll have to put backslashes before the `+' signs in the regexp, as they're special characters in regexps.
 
Wow, boolean range operator, had to look that one up again. Definitely falls under the "that's neat and something I wouldn't have thought of" star category. It's good to be impressed every now and then. :-D

oops on the +, I swear I know better :)

________________________________________
Andrew

I work for a gift card company!
 
It's a sweet time-saver at times. I wish Java had something similar, as that's what I'm required to use at the moment.

Actually, the '+' had me too for a minute. Too busy a) remembering if angle brackets were special in regexps and b) looking at your example :p I guess the difference is that I tested it first, eh?!? :-D
 
Yeah, in my example I was too busy thinking how much I like short circuit boolean operators. I do most of my work in VB.NET these days, and they have two sets of logical operators. If you use "And" it doesn't short circuit, but if you use "AndAlso", it does. Considering I have no idea what case I wouldn't want a short circuit, I'm constants reminded of the fact as I have to type the long versions every time.

Man, I miss Perl. These forums are about all I see of it anymore. :-/

________________________________________
Andrew

I work for a gift card company!
 
wow, thanks so much guys!

they just told me today they want it done and that was the last thing holding me up, thanks soooooo much!!!! :)

i love perl, but i'm starting to use Java for some of my apps. but i don't know if i'm ever going to stop using it. i understand it a whole lot better then any other lang.
 
hmmmm... ok, i tried to do it and i'm not sure if its right, or even close, but i got a server error.

the $topic.gosh file will look something like this..
Code:
0ISTARTI0
Username1
Post Date
0aaAAaa0
first post
multi line post here.
multi line post here.
lots of lines in this.
0zzZZzz0

0ISTARTI0
Username2
Post Date
0aaAAaa0
multi line post here. second post
multi line post here.
lots of lines in this.
0zzZZzz0

0ISTARTI0
Username3
Post Date
0aaAAaa0
multi line post here. this is 
a third post
0zzZZzz0

and i tried...
Code:
open (DATA, "topics/$topic.gosh");
my @topic_posts = <DATA>;
close (DATA);

for ($i = 0; $i <= $#topic_posts; $i++){
	if ($topic_posts[$i] =~ /0ISTARTI0/){

	$username = $topic_posts[$i + 1]
	
	/0aaAAaa0/ .. /0zzZZzz0/ and print for ( @post{$i} );
	
	}
    print "$username Posted: @post{$i}";
  }

Thanks Sooooooo much for your time!

~Nate_Bro
 
ahhhhhh, i wish you could edit your posts

$username = $topic_posts[$i + 1];

:)
 
here is where i'm at...

it prints everything but the post... i'm stuck :(

any ideas would be awsome :D thanks sooooo much!

Code:
#!/usr/bin/perl -w
use CGI qw(:standard);
use CGI::Carp qw(warningsToBrowser fatalsToBrowser);
use Socket;

my $forum_name = param(forum_name);
my $topic = param('top');

print <<END;
Content-Type: text/html\n\n
<hr>
END

if ($topic){

open (DATA, "topics/$topic.gosh");
my @topic_posts = <DATA>;
close (DATA);

my $number_of_posts;

for ($i = 0; $i <= $#topic_posts; $i++){
	if ($topic_posts[$i] =~ /0ISTARTI0/){

	$username = $topic_posts[$i + 1];
	$post_date = $topic_posts[$i + 2];
	@post;
	$topic_posts[$i + 3] =~ /0aaAAaa0/ .. /0zzZZzz0/ and print for ( @post );
	
print <<END;
Date Posted: $post_date<br>
$username Posted: @post<p>
END
	}
  }
}
print "<hr>";
 
The data file structure is terrible (sorry to sound critical). If you can you should redo the data file. Make every post a line of its own in the file and use delimiters between fields:

name|date|message
name|date|message
etc
etc
etc
 
ok, thanks, i'm new at this, so thank you.
i didn't know, now i do :)
 
Problems you will need to address offered for consideration:

do not allow the file delimiter to be passed into the data fields, in my example that would be | you just use a tr operator to remove it:

my @data_fields = ($name, $date, $message);
tr/\|//d for @data_fields

newlines will need to also be removed so the flat file isn't "broken":

s/\n//g for @data_fields;

or change them to a character for later substitution when the message is displayed:

$message =~ s/\n/\[n\]/g;

when the file is opened and before the message is displayed convert it back to a newline (preserves formatting of the original message if thats a concern)

$message =~ s/\[n\]/\n/g;
 
awsome! thanks sooooo much!

i don't know what i would have done without you all!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top