2017-03-07 40 views
2

如何编写至少包含一个字母但第一个字符不能是数字的正则表达式?我想这匹配包含字母的字符串,其中第一个字符不是数字

str = "a" 
str =~ /^[^\d][[:space:]]*[a-z]*/i 
# => 0 

str = "=" 
str =~ /^[^\d][[:space:]]*[a-z]*/i 
# => 0 

"=" is matched even though it contains no letters. I expect the “一” to match, and similarly a string like “3abcde”`应该不匹配。

+1

' [az] *'和'[[:space:]] *'可以匹配空字符串,'='不是数字,匹配w ith'[^ \ d]'。试试'/ \ A(?!\ d)。* [a-zA-Z]。* \ z/m'甚至是'/\A(?!\d).*\p{L}.*\z/m' –

+0

另一种方式是'str [0]!〜/ \ d/&& str =〜/ [[:alpha] /#=> 4'(truthy) –

回答

1

[a-z]*[[:space:]]*模式可以匹配一个空字符串,所以他们并不真正使任何区别时验证是必要的。另外,=不是一个数字,它与[^\d]否定字符类相匹配,即消费模式类型。这意味着它需要字符串中的数字以外的字符。

你可以指望在先行将限制字符串的位置开始:

/\A(?!\d).*[a-z]/im 

甚至有点快和Unicode的版本:

/\A(?!\d)\P{L}*\p{L}/ 

regex demo

详情

  • \A - 串
  • (?!\d)的开始 - 第一个字符不能是数字
  • \P{L}* - 0或更多(*)字符除字母

  • .*其他 - 任何0+字符,包括换行符如果使用/m修改)
  • \p{L} - 信

m修饰符使.匹配Ruby正则表达式中的换行符。

使用[a-z]当您需要将字母限制在ASCII表中的字符时。另外,\p{L}可以用[[:alpha:]]\P{L}[^[:alpha:]]替代。

+1

您可不写'/ \ A(?!\ d)。* [az]/im'或可能更快)'/ \ A(?!\ d)。*?[az]/im'? –

+1

@CarySwoveland你是对的。这个答案包括一些冗余。但我不认为贪婪的比赛会更快。 – sawa

+0

@sawa,你是不是非贪心? –

0

如果两个正则表达式被允许你可以写:

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 

如果你想truefalse返回,改变工作线:

str[0] !~ /\d/ && str =~ /[[:alpha]]/) ? true : false 

!!(str[0] !~ /\d/ && str =~ /[[:alpha]]/) 
相关问题