正则表达式:匹配包含数字和字母的字符串,但不包含只是数字的字符串
题
我希望能够使用单个正则表达式(如果可能)要求字符串适合[A-Za-z0-9_]
但不允许:
- 字符串只包含数字或/和符号。
- 以符号开头或结尾的字符串
- 彼此相邻的多个符号
有效
-
test_0123
-
t0e1s2t3
-
0123_test
-
te0_s1t23
-
t_t
无效
-
t__t
-
____
-
01230123
-
_0123
-
_test
-
_test123
-
test_
-
test123_
规则的原因
这样做的目的是过滤我正在处理的网站的用户名。 出于特定原因,我已达到规则。
-
仅包含数字和/或符号的用户名可能会导致路由和数据库查找出现问题。
/users/#{id}
的路由允许id
为用户的id或用户的名称。 所以名称和ID不应该碰撞。 -
_test
看起来很奇怪,我不相信它是有效的子域名,即_test.example.com
-
我不喜欢
t__t
作为子域的外观。 即t__t.example.com
这完全符合您的要求:
/\A(?!_)(?:[a-z0-9]_?)*[az](?:_?[a-z0-9])*(?
- 至少一个字母字符(中间的
[az]
)。 - 不以下划线开头或结尾(开头和结尾的
(?!_)
和(? )。
- 字母字符前后可以包含任意数量的数字,字母或下划线,但每个下划线必须至少用一个数字或字母(其余部分)分隔。
编辑:事实上,由于正则表达式的其余部分是如何工作的,你甚至可能根本不需要前瞻/外观?:
第一个?:
括号将不允许下划线直到字母数字后,第二个?:
括号赢了' t允许下划线除非它在字母数字之前:
/\A(?:[a-z0-9]_?)*[az](?:_?[a-z0-9])*\z/i
应该工作正常。
我确信你可以将所有这些都放在一个正则表达式中,但这并不简单,我不确定为什么坚持它是一个正则表达式。 为什么不在validation期间使用多次传递? 如果在用户创建新帐户时完成validation检查,则没有任何理由尝试将其填充到一个正则表达式中。 (也就是说,你只会一次处理一个项目,而不是数百或数千或更多。对于正常大小的用户名,几次传递应该花很少的时间,我想。)
如果名称不包含至少一个数字,则首先拒绝; 如果名称不包含至少一个字母,则拒绝; 然后检查开始和结束是否正确; 这些传递中的每一个都可以是易于阅读和易于维护的正则表达式。
关于什么:
/^(?=[^_])([A-Za-z0-9]+_?)*[A-Za-z](_?[A-Za-z0-9]+)*$/
它不使用后向引用。
编辑:
成功完成所有测试用例。 ruby是否兼容。
这不会阻止“__”,但它确实得到了其余的:
([A-Za-z]|[0-9][0-9_]*)([A-Za-z0-9]|_[A-Za-z0-9])*
这是获得所有规则的更长forms:
([A-Za-z]|([0-9]+(_[0-9]+)*([A-Za-z|_[A-Za-z])))([A-Za-z0-9]|_[A-Za-z0-9])*
dang,那很难看。 我同意Telemachus,你可能不应该用一个正则表达式做这个,即使它在技术上是可行的。 正则表达式通常是维护的痛苦。
这个问题要求一个正则表达式,并暗示它应该是匹配的正则表达式,这很好,并且由其他人回答。 但是,为了兴趣,我注意到这些规则更容易直接表示为不匹配的正则表达式。 即:
x !~ /[^A-Za-z0-9_]|^_|_$|__|^\d+$/
- 除了字母,数字和_之外没有其他字符
- 不能以_开头
- 不能以_结尾
- 不能连续两个_s
- 不能全部数字
你不能在Rails validates_format_of中以这种方式使用它,但你可以将它放在类的validation方法中,我认为你有更好的机会仍然能够理解你的意思,一个月或从现在起一年。
干得好:
^(([a-zA-Z]([^a-zA-Z0-9]?[a-zA-Z0-9])*)|([0-9]([^a-zA-Z0-9]?[a-zA-Z0-9])*[a-zA-Z]+([^a-zA-Z0-9]?[a-zA-Z0-9])*))$
如果要限制要接受的符号,只需使用包含所有允许符号的[]更改所有[^ a-zA-Z0-9]
(?=.*[a-zA-Z].*)^[A-Za-z0-9](_?[A-Za-z0-9]+)*$
这个有效。
向前看以确保字符串中至少有一个字母,然后开始消耗输入。 每次有下划线时,下一个下划线前必须有一个数字或一个字母。
/^(?![\d_]+$)[A-Za-z0-9]+(?:_[A-Za-z0-9]+)*$/
您的问题基本上与此问题相同,并且要求至少有一个字符必须是字母。 负向前瞻 – (?![\d_]+$)
– 负责处理那部分,并且比其他人试图做的更容易(包括读写),而不是将其纳入基本正则表达式。
[A-Za-z][A-Za-z0-9_]*[A-Za-z]
这适用于你的前两个规则(因为它需要一个字母在开头和结尾为第二个规则,它自动需要字母)。
我不确定第三条规则是否可以使用正则表达式。