类似Twitter的用户名的正则表达式是什么?

8
我已经编程一段时间了,但直到最近才有正则表达式的需求。我需要编写一个正则表达式,接受 Twitter 用户名。基本上,我想允许每次使用一个下划线。名称中可以有多个下划线,但这些不应是连续字符。字母数字字符也是允许的。但数字不能作为名称的开头。
以下名称是有效的:
- _myname67 - myname67 - my_name - _my_67_name_
以下名称无效:
- 94myname - __myname - my__name - my name 我在 Rubular 上尝试了几个正则表达式:
- /^[^0-9\s+](_?[a-z0-9]+_?)+$/i - /^([a-z_?])+$/i
我遇到的问题是这些表达式匹配了多个下划线。
6个回答

10

编辑过的

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"]

你应该只在想要捕获的子字符串上使用( )。而(?: )则用于你不需要捕获的分组。如果你不需要特别引用那个子字符串,那么使用它是一个好习惯。这也会使正则表达式运行更快。


确实简洁。但是尽管我很想将其选为正确答案,它与Hrant Khachatrian介绍的测试字符串“m_yname”不匹配。然而,这教会了我一些新东西。请解释一下您所拥有的 ?: 表达式。 - Igbanam
正如Yasky所指出的那样,正则表达式存在问题。我已经修复了它。 - sawa
如何包含以数字开头的名称,但不允许只包含数字的名称。 - lightsaber

2
请尝试以下内容:^([a-zA-Z](_?[a-zA-Z0-9]+)*_?|_([a-zA-Z0-9]+_?)*)$ 我将这个问题分为两种情况:单词以字母开头和单词以下划线开头。如果您不想允许仅由一个符号组成的名称,请用+替换*
maerics的解决方案有一个问题,它无法捕获第二个位置有_的名称,例如m_yname

+1,但这个允许使用下划线作为用户名,这并不理想。 - iwasrobbed

1

这看起来是可行的:

/^(_|([a-z]_)|[a-z])([a-z0-9]+_?)*$/i

更新:已修正数字限制和大小写。


这只是一个示例,以展示如何处理连续下划线问题。 - DigitalRoss
@sawa 这会检查下划线或字母是否在下划线或仅字母仅在初始位置之前。它应该通过测试。 - Igbanam
在正则表达式后面加上'i'可以处理大小写不敏感的情况。 - Igbanam

1

有些东西很难仅使用正则表达式来表达,并且通常是只写不读的(也就是说,后来没有办法阅读和理解它们)。您可以在 Ruby 代码中使用更简单的正则表达式(例如您成功编写的两个正则表达式),并检查双下划线。这不会有任何影响:

if username =~ /^[^0-9](_?[a-z0-9]+_?)+$/i and username.count('__') == 0 then ...


这不起作用:多个非连续的下划线将会失败,这不符合原帖作者的要求。 (-1) - Platinum Azure
是的,但这仍然是一个好方法 - 我编辑了答案,使得username.count('__') > 0,这解决了你提到的缺陷...至少如果count()按照我所假设的那样工作。 - Brian Schroth
不,它不是(尽管我愚蠢地投票批准了编辑)。你希望它等于零。 - Platinum Azure
哈,我刚刚重新编辑了一下,因为我意识到它原来有些混乱!这就是我的报应,因为我试图在一个我不太熟悉的语言中修复答案。现在我放弃了,我可能又把它搞砸了 :P - Brian Schroth
是的,非常抱歉,我刚刚读帖子太快了。现在已经修复了,谢谢Brian。 - Gabriel

0

有些问题不能仅通过一个正则表达式来解决...特别是当你想要检查模式的缺失以及另一个模式的存在时。

有时候,将条件分解为多个正则表达式并逐个匹配会更好(而且肯定更易读)。

除了使用正则表达式来检查有效字符之外,您还应该使用正则表达式来检查两个下划线的存在,并反转该结果(即,如果名称与该模式匹配,则放弃该名称)。


1
或者您可以使用@sawa的答案,它使用单个(但更难阅读)正则表达式完成工作。 - Platinum Azure
1
我认为你的回答意味着不能用一个正则表达式完成。在第二句中,你使用了“更好”的词汇,这意味着有一种非更好的方法来完成它,但不足以排除第一句的暗示。 - sawa
1
公正的观点,不过我认为你在解析方面太过字面了。已经进行编辑。 - Platinum Azure

0
/^[A-Za-z_]([A-Za-z0-9]+_?)+$/

上帝知道为什么。Rubular认为这个很好用 [编辑 - 除了Hrant提到的“m_yname”的情况]。非常感谢。 - Igbanam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接