Reputation: 19110
How do I write a regular expression that has at least one letter, but the first character must not be a number? I tried this
str = "a"
str =~ /^[^\d][[:space:]]*[a-z]*/i
# => 0
str = "="
str =~ /^[^\d][[:space:]]*[a-z]*/i
# => 0
The "=" is matched even though it contains no letters. I expect the
"a"to match, and similarly a string like
"3abcde"` should not match.
Upvotes: 2
Views: 157
Reputation: 626747
The [a-z]*
and [[:space:]]*
patterns can match an empty string, so they do not really make any difference when validating is necessary. Also, =
is not a digit, it is matched with [^\d]
negated character class that is a consuming type of pattern. It means it requires a character other than a digit in the string.
You may rely on a lookahead that will restrict the start of string position:
/\A(?!\d).*[a-z]/im
Or even a bit faster and Unicode-friendly version:
/\A(?!\d)\P{L}*\p{L}/
See the regex demo
Details:
\A
- start of a string(?!\d)
- the first char cannot be a digit\P{L}*
- 0 or more (*
) chars other than letters.*
- any 0+ chars, including line breaks if /m
modifier is used)\p{L}
- a letterThe m
modifier enables the .
to match line break chars in a Ruby regex.
Use [a-z]
when you need to restrict the letters to those in ASCII table only. Also, \p{L}
may be replaced with [[:alpha:]]
and \P{L}
with [^[:alpha:]]
.
Upvotes: 1
Reputation: 110675
If two regular expressions were permitted you could write:
def pass_de_test?(str)
str[0] !~ /\d/ && str =~ /[[:alpha]]/
end
pass_de_test?("*!\n?a>") #=> 4 (truthy)
pass_de_test?("3!\n?a>") #=> false
If you want true
or false
returned, change the operative line to:
str[0] !~ /\d/ && str =~ /[[:alpha]]/) ? true : false
or
!!(str[0] !~ /\d/ && str =~ /[[:alpha]]/)
Upvotes: 0