arrow has asked for the wisdom of the Perl Monks concerning the following question:

I've been trying for a while now to simply (or not so simply) construct a regex to deny any characters others than lowercase letters, hyphens, and spaces. Simple, no? NO! I've tried every combination I could think of including making to match statments, one to try to match the lowercase letters, hypens, and spaces, and one to match all the characters I didn't want. Here are some of my desperate attempts:

/[a-z]+(?:[a-z\s-] *)/ (current)
/[a-z]+[-\s]*/
/[-\s(a-z)+]*/

but obviously none of them have worked. Any suggestions?

P.S. Thanks jwest for giving me the first one.

Just Another Perl Wannabe

Edit by tye, change title, close CENTER tag

Replies are listed 'Best First'.
Re: so close, yet so far away...
by gjb (Vicar) on Dec 06, 2002 at 21:29 UTC

    Unless I get you completely wrong (which seems probable) wouldn't just /^[a-z\- ]*$/ do what you want? Note that this also matches the empty string, replace + by * if you don't want that.

    Hope this helps, -gjb-

Re: (nrd) so close, yet so far away...
by newrisedesigns (Curate) on Dec 06, 2002 at 21:30 UTC
Re: so close, yet so far away...
by BrowserUk (Patriarch) on Dec 06, 2002 at 21:31 UTC

    Try this.

    for $w ('abd -def', 'Abcdef', 'abd_def', "abd\tdef") { print $w, $w =~ /^[-a-z\ ]+$/ ? 'ok' : 'not ok',$/ } abd -def ok Abcdef not ok abd_def not ok abd def not ok

    Use !~ to invert the match.


    Okay you lot, get your wings on the left, halos on the right. It's one size fits all, and "No!", you can't have a different color.
    Pick up your cloud down the end and "Yes" if you get allocated a grey one they are a bit damp under foot, but someone has to get them.
    Get used to the wings fast cos its an 8 hour day...unless the Govenor calls for a cyclone or hurricane, in which case 16 hour shifts are mandatory.
    Just be grateful that you arrived just as the tornado season finished. Them buggers are real work.

Re: so close, yet so far away...
by dws (Chancellor) on Dec 06, 2002 at 21:32 UTC
    I've been trying for a while now to simply (or not so simply) construct a regex to deny any characters others than lowercase letters, hyphens, and spaces.   if ( $string =~ /[^a-z- ]/ ) { ... } will tell you if there are errant characters in $string.

Re: so close, yet so far away...
by UnderMine (Friar) on Dec 06, 2002 at 21:28 UTC
    Assuming that you wish to reject partial hyphenated words ie. 'this-' and '-that'
    $string !~ /^(?:(?<!-)(?:[-a-z])*(?<!-)\s*)+$/
    I think... gets out the console

    Update forgot to ^$ it and invert it.. doh.

    Hope it helps
    UnderMine

Re: regex to deny characters?
by arrow (Friar) on Dec 08, 2002 at 18:22 UTC
    gjb and newrisedesigns, you did have me wrong. I needed at least one lower case letter and the ability to accept an optional hypen or space. In other words:
    sdlfj   OK
    dsfj-dlf   OK
    dish dslf   OK
    dsf-ldj sdf   OK
    -   NOT OK
     (space character)   NOT OK
    *$)#&%_!@...   NOT OK

    Just Another Perl Wannabe
      OK, so you were pretty close:
      while (<DATA>) { chomp; print "$_ "; if (/^[a-z][a-z \-]*/) { print "OK\n"; } else { print "NOT OK\n"; } } __DATA__ sdlfj dsfj-dlf dish dslf dsf-ldj sdf - *$)#&%_!@...

      -- Dan