in reply to Removing similar characters

Regex will surely be your friend here. Do you want to remove from the string, replace them with new random chars, or throw out the password entirely and regenerate a new random string?

I would use character classes for each set of things you want to be track duplicates for, with something like the below.

my $password = 'a8f3%djk$'; # some random string if ($password =~ m/[[:alpha:]]{3,}|\d{3,}|[\^@\(]{3,}/) { # regenerate password }

You could use a character class like [A-Za-z] instead of [[:alpha:]] if you know you will only see ascii character. You will likely have to add to the [\^@\(] character class any other symbols you want. The other option is to exclude anything you don't want to match in that class. Maybe [^0-9A-Za-z] is enough there.

Replies are listed 'Best First'.
Re^2: Removing similar characters
by rspishock (Monk) on Sep 01, 2011 at 22:41 UTC

    Thanks for the tip. I was guessing that using a regex was probably going to be one of the best ways to achieve this. Since I'm not too familiar with using regex, my question is can I direct the regex to the array which contains the characters? For example, since I want to be able to check 88 individual characters for duplicates.

    Below is a small portion of the script that I'm working on.

    my @chars6 = ('0'..'9', 'a'..'z', 'A'..'Z', '!','@', '#', '$', '%', '^', '&', '*', '(', ')', '<', '>', '?', '`', '+', '/', '[', '{', ']', '}', '|', '=', '_','~', ',', '.'); if ($level == 5) { m/@chars6/ #generate new password }

    Looks like I'm off to Amazon to get a book to start learning regex.

      A better bet is to generate a string from that array and insert it into the regex pattern. I did this below with the string $chars6_class. Note that I escaped many of the symbols which have special meaning in regex and perl, though I didn't really double check I got all the right ones.

      Then I use the back reference, \1, to look for two more occurrences of what I just found.

      my @chars6 = ('0'..'9', 'a'..'z', 'A'..'Z', '!','\@', '#', '\$', '\%','^', '&', '\*', '\(', '\)', '<', '>', '\?', '`', '\+', '\/', '\[', '\{', '\]','\}', '\|', '=','_', '~', ',', '\.'); my $chars6_class = '[' . join( '', @chars6) . ']'; if ($password=~ m/($chars6_class)\1{2}/) { # regenerate password }

      Further, I would take a look at the posix character classes to see if there is already a set of what you are looking for. My guess would be that you could just use the below regex instead of dealing with an array of characters.

      m/([[:alnum:]]|[[:punct:]])\1{2}/