tags:

views:

61

answers:

6

hi - why is this expression returning true for character 1 or V (and others)? how could i rewrite it so that it would return true only when its blank or a character a-z?

~((^$)||(^[a-z]$))~
+1  A: 

It matches because the expression contains ||. The regex 'or' operator is a single |; two of them means 'or nothing or', and every string will match an empty expression with no anchors.

Either way, your regex seems a bit complex...how about /^([a-z]?)$/?

cHao
+7  A: 

Your problem is in the middle:

||

That means:

OR the empty string OR

And the empty string can be between any character. Or no characters. Basically, you're saying "Match anything."

To do an OR with a regex, only use a single pipe.

You can simplify this to:

/^[a-z]?$/
Robert P
+2  A: 

Empty string or one character in the range a-z would be:

/^[a-z]?$/

Remember that ? means "0 or 1 of this" -- so the regexp translates to "0 or 1 character between a and z inclusive".

Rewriting it to use an | for "or" (note how much more ugly it is, so this is just an academic exercise at this point) you could do:

# nothing, or one character in a-z
/^(?:|[a-z])$/
Ether
@Ether: Your last expression should match any string that has a start -- ie: everything.
cHao
Your second one is still a bit off :) `perl -e "my $foo = '#!@#'; print $foo =~ /^|[a-z]$/ ? 'matches' : 'not match'"` prints `matches` (the `|` goes across the entire regex.)
Robert P
@Robert, @cHao: hmm you're right, I got the binding order mixed up. time for parentheses! :)
Ether
you want `?:`, not `:?`.
sreservoir
@sreservoir: yes I do, thanks!
Ether
A: 

Couldn't you change it to something like this:

^([a-z]?)$
mattmc3
+2  A: 

This is an example of why you should prefer \z rather than $ to mean "end of string". The pattern /^[a-z]?$/ will happily match a string consisting of a single newline.

#!/usr/bin/perl

use strict; use warnings;

my $s = "\n";

if ( $s =~ /^[a-z]?$/ ) {
    print "string consisting of a single newline matched\n";
}

unless ( $s =~ /^[a-z]?\z/ ) {
    print "string consisting of a single newline did not match\n";
}
Sinan Ünür
wow thanks for the tip
audio.zoom
Sinan is a true expert.
Kinopiko
@Kinopiko Thank you for the compliment. It's just gotchas like this stick in my mind once I have been bitten.
Sinan Ünür
A: 
/\A(\p{Lower})?\z/
Axeman