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

Discussion in 'Perl' started by Jonathan, Dec 24, 2003.

  1. Jonathan

    Jonathan Guest

    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..?
     
    Jonathan, Dec 24, 2003
    #1
    1. Advertising

  2. Jonathan

    Guest

    "Jonathan" <> wrote in message news:<bscmih$49c$1.nb.home.nl>...
    > 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.
     
    , Dec 25, 2003
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?UnVkeQ==?=

    to store or not to store an image

    =?Utf-8?B?UnVkeQ==?=, Mar 29, 2005, in forum: ASP .Net
    Replies:
    6
    Views:
    645
    =?Utf-8?B?UnVkeQ==?=
    Mar 30, 2005
  2. crichmon
    Replies:
    4
    Views:
    486
    Mabden
    Jul 7, 2004
  3. Replies:
    5
    Views:
    254
    John Machin
    Nov 5, 2006
  4. Dilip
    Replies:
    8
    Views:
    324
    Jerry Coffin
    Sep 18, 2006
  5. Anton81

    Substitutions in matched patterns?

    Anton81, Jan 31, 2006, in forum: Perl Misc
    Replies:
    4
    Views:
    96
    it_says_BALLS_on_your forehead
    Jan 31, 2006
Loading...

Share This Page