There are two main approaches to construct a regular expression for this purpose. First is to make sure that all symbols are allowed. Another is to make sure that no symbols are not allowed. And you can also use the transliteration operator instead. Here's a benchmark:
use Benchmark 'cmpthese';
my @chars = ('0' .. '9', 'A' .. 'Z', 'a' .. 'z');
my $randstr = map $chars[rand @chars], 1 .. 16;
sub nextstr() { return $randstr++ }
cmpthese 1000000, {
regex1 => sub { nextstr =~ /\A["#&'(),\-.\/0-9:;A-Za-z]*\z/ },
regex2 => sub { nextstr !~ /[^"#&'(),\-.\/0-9:;A-Za-z]/ },
tr => sub { (my $dummy = nextstr) !~ y/"#&'(),\-.\/0-9:;A-Za-z/"#&'(),\-.\/0-9:;A-Za-z/c },
};
Results:
Rate regex1 regex2 tr
regex1 137552/s -- -41% -60%
regex2 231481/s 68% -- -32%
tr 341297/s 148% 47% --