$ perl -E ' my @x = (qw{A AA AAA _ __ ___ -A A- A.A A. .A A-A A_A}, "A\n", "A\tA"); my $re = qr{\A[A-Za-z0-9](?:[A-Za-z0-9_.-]*?[A-Za-z0-9]|)\z}; say "|$_| is ", /$re/ ? "OK" : "BAD" for @x ' |A| is OK |AA| is OK |AAA| is OK |_| is BAD |__| is BAD |___| is BAD |-A| is BAD |A-| is BAD |A.A| is OK |A.| is BAD |.A| is BAD |A-A| is OK |A_A| is OK |A | is BAD |A A| is BAD