我已经编码了一段时间,但直到最近才需要正则表达式。我需要做一个正则表达式,像Twitter一样接受用户名。基本上,我想一次允许一个下划线。名称中可以有多个下划线,但这些下划线不应是连续字符。还允许使用字母数字字符。但是数字不能以名字开头。
名称如
- _myname67
- 我的名字67
- my_name
- _my_67_name_
有效,但
- 94我的名字
- __myname
- my__name
- 我的名字
无效。
我玩过 Rubular 并想出了几个正则表达式:
-
/^[^0-9s+](_?[a-z0-9]+_?)+$/i
-
/^([a-z_?])+$/i
我一直遇到的问题是这些匹配多个下划线。
已编辑
a = %w[
_myname67
myname67
my_name
_my_67_name_
94myname
__myname
my__name
my name
m_yname
]
p a.select{|name| name =~ /A_?[a-z]_?(?:[a-z0-9]_?)*z/i}
# => ["_myname67", "myname67", "my_name", "_my_67_name_", "m_yname"]
应仅对要捕获的子字符串使用( )
。 (?: )
用于您不想捕获的分组。最好在不需要特别引用该子字符串时使用它。它还使正则表达式运行得更快。
尝试以下^([a-zA-Z](_?[a-zA-Z0-9]+)*_?|_([a-zA-Z0-9]+_?)*)$
我区分了两种情况:单词以字母开头,以下划线开头。如果不想允许名称由一个符号组成,请仅将*
替换为 +
。
Maerics的解决方案有一个问题,它不会捕获在第二位_
的名称,例如m_yname
有些东西真的很难只用正则表达式来表达,而且通常是只写的(也就是说,最近没有办法阅读和理解它们)。您可以使用更简单的正则表达式(例如您设法编写的两个正则表达式)并检查 Ruby 代码中的双下划线。它无妨:
if username =~ /^[^0-9](_?[a-z0-9]+_?)+$/i and username.count('__') == 0 then ...
似乎有效:
/^(_|([a-z]_)|[a-z])([a-z0-9]+_?)*$/i
更新:更正了数字约束和大小写。
/^[A-Za-z_]([A-Za-z0-9]+_?)+$/
有些问题不能只用一个正则表达式来解决......特别是当您想检查是否存在一种模式以及是否存在另一种模式时。
有时,将您的条件分解为多个正则表达式并依次匹配每个正则表达式会更好(而且绝对更具可读性)。
除了使用正则表达式检查有效字符外,还应该使用正则表达式检查是否存在两个下划线,然后反转该结果(即,如果名称与模式匹配,则将其丢弃)。