How do I not store matched patterns in the $1.. strings?

J

Jonathan

Ok, I have this script:

#!perl
print "Content-type: text/html\n\n";
$test[0]="Text0<\$UserA|UserB|UserC|5|>Text1";
$test[1]="Text2";
$test[2]="Text3</\$>";
my $User="UserD";
my $Rights="6";
my $Text=join "ARRAYJOINER",@test;
$Text=~s{<\$(([A-Za-z0-9-_
']+\|)+)>(.*?)</\$>}{(index("\$$1","\$$User\|")!=-1 ||
index($1,"\|$User\|")!=-1 || "\$$1"=~/(\$|\|)[0-$Rights]\|/)?$3:""}egs;
@test=split(/ARRAYJOINER/, $Text);
print $Text;
exit;

What I want is for the script to not display the text in between
<$UserA|UserB|UserC|5|> and </$> unless a person is UserA, -B, -C or has
level 5 (or higher) rights. This means that when I use this on my system,
only Admins, who are level 6 and Moderators, who are level 5, will be able
to see "Text1Text2Text3"

I thought about this and came to the conclusion this should be possible in
one line. At least the =~ part of it...when I have an idea in my head, Im
not gonna be able to get it out :D, so I really wanna give it a try...

The index(..) part of the code works, if the user matches it will paste the
text ($3), but the other part of it doesn't. I had to use m// for it to
allow not only the users with the same rights as needed but also with more
rights than needed. ([0-$Rights])...I think the problem is that the m//
operator clears the $3 string and gives it a different value (""). So, how
do I make perl not store the matched pattern in $1..?
 
N

nobull

Jonathan said:
Ok, I have this script:

#!perl
print "Content-type: text/html\n\n";
$test[0]="Text0<\$UserA|UserB|UserC|5|>Text1";
$test[1]="Text2";
$test[2]="Text3</\$>";

You forgot to declare @test - use strict would have noticed this for
you.
my $User="UserD";
my $Rights="6";

Why "6" not 6? Yeah Perl will convert the string to a number when
necessary but why makar it do so?
my $Text=join "ARRAYJOINER",@test;
$Text=~s{<\$(([A-Za-z0-9-_
']+\|)+)>(.*?)</\$>}{(index("\$$1","\$$User\|")!=-1 ||
index($1,"\|$User\|")!=-1 || "\$$1"=~/(\$|\|)[0-$Rights]\|/)?$3:""}egs;
@test=split(/ARRAYJOINER/, $Text);
print $Text;
exit;

What I want is for the script to not display the text in between
<$UserA|UserB|UserC|5|> and </$> unless a person is UserA, -B, -C or has
level 5 (or higher) rights. This means that when I use this on my system,
only Admins, who are level 6 and Moderators, who are level 5, will be able
to see "Text1Text2Text3"

I thought about this and came to the conclusion this should be possible in
one line. At least the =~ part of it...when I have an idea in my head, Im
not gonna be able to get it out :D, so I really wanna give it a try...

The index(..) part of the code works, if the user matches it will paste the
text ($3), but the other part of it doesn't. I had to use m// for it to
allow not only the users with the same rights as needed but also with more
rights than needed. ([0-$Rights])...I think the problem is that the m//
operator clears the $3 string and gives it a different value (""). So, how
do I make perl not store the matched pattern in $1..?

You don't you just copy it elsewhere.

BTW: Whitespace is free. On a related matter I'd tend to use the
long-hand if-else rather than ?: for stuff that's more than
comfortably can be taken in in one glance.

You can put many statements inside the RHS of s///e but the parsing
rules of the RHS of s/// are rather gory so whenever I have a
non-trivial s///e I take the code outside.

my $s = sub {
my $t = $3;
if ( index("\$$1","\$$User\|")!=-1 ||
index($1,"\|$User\|")!=-1 ||
"\$$1"=~/(\$|\|)[0-$Rights]\|/ ) {
$t;
} else {
"";
}
};

$Text=~s/<\$(([A-Za-z0-9-_ ']+\|)+)>(.*?)</\$>/&$s/egs;

Note: I still think all this stuff with index() is a bit unreadable
and a bit long. You should always try to make your code as readable
as possible. Often making it shorter actually makes it clearer too.

if ( $1 =~ /(^|\|)($User|[0-$Rights])\|/ )

This newsgroup does not exist (see FAQ). Please do not start threads
here. Merry Christmas.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top