Bijou Trouvaille
Bijou Trouvaille

Reputation: 9434

Perl regex testing blank or expression

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 it's blank or a character from a-z?

~((^$)||(^[a-z]$))~

Upvotes: 0

Views: 2122

Answers (6)

Ether
Ether

Reputation: 53966

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])$/

Upvotes: 2

Axeman
Axeman

Reputation: 29854

/\A(\p{Lower})?\z/

Upvotes: 0

Sinan Ünür
Sinan Ünür

Reputation: 118128

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";
}

Upvotes: 2

Robert P
Robert P

Reputation: 15968

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]?$/

Upvotes: 8

mattmc3
mattmc3

Reputation: 18335

Couldn't you change it to something like this:

^([a-z]?)$

Upvotes: 0

cHao
cHao

Reputation: 86525

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]?)$/?

Upvotes: 1

Related Questions