【问题标题】:What is the meaning of this regex expression?这个正则表达式的含义是什么?
【发布时间】:2014-01-08 06:41:53
【问题描述】:

我正在一个教授 python(learnstreet.com) 的网站上做一个基于验证的项目。 该项目的一个要求是必须使用正则表达式来验证用户输入的各个字段。

项目的第一部分是用户名验证。网站为用户名定义的约束是:

               Method 1 - Username Validation 

如果提供了用户名,则返回 True 是有效的,否则为 False。如果用户名至少为 5,则该用户名有效 字符长且没有空格或特殊字符(例如非字母数字) 字符。

我的解决方案不正确。该网站为我提供了以下用于用户名验证的正则表达式:

^[a-zA-Z0-9_]+$.

这个表达式中的+$是什么意思?

另外,考虑到用户名不能有任何非数字字符,而且这个表达式在集合中包含下划线,这难道不是不正确的吗?

【问题讨论】:

  • ^$ 是用于表示正则表达式开始和结束的锚。 [] 是一个字符类。 + 表示 1 个或多个字符。
  • 为什么不len(username) >= 5 and username.isalpha()
  • @devnull 谢谢你这么快!此外,在这种情况下,上述正则表达式与 ^\w+$ 有何不同。这是我在解决方案中提交的正则表达式,被标记为不正确。
  • @VineetKaushik 如果您想确保长度至少为5,请在您的正则表达式中使用{5,} 而不是+
  • @devnull 虽然我确实使用条件来检查用户名的长度,但我会记住这一点。

标签: python regex validation


【解决方案1】:

^ 是行首锚点,仅匹配行首。

$ 是行尾锚点,仅匹配行尾。

[a-zA-Z0-9_] 是一个接受字母、数字和下划线的字符类。

+ 是一个量词,表示前一个字符或组的 1 倍或更多倍。

[a-zA-Z0-9_]+ 将因此匹配至少 1 个字母、数字或下划线。


我个人会使用:

^[a-zA-Z0-9]{5,}$

用于验证,因为它还考虑到用户名中至少有 5 个字符。

{n,m} 是一个变量量词,最小重复为n,最大重复为m。如果省略n,则相当于0 到m 次。如果省略m,则相当于n 最少重复,最多无限重复。

{5,} 因此意味着至少 5 次重复。

我不会使用下划线,因为我认为它是一个特殊字符,但我想这可能被认为是主观的。

顺便提一下,\w 在正则表达式中被称为单词字符,大致相当于[a-zA-Z0-9_],这可能是该网站的含义。

【讨论】:

    【解决方案2】:

    具体分解这一切,你得到了这个正则表达式字符串:

    ^[a-zA-Z0-9_]+$
    

    第一个子句是^,在这种情况下,它只是表示字符串的开始。

    第二个子句是[a-zA-Z0-9_]+,表示[a-zA-Z0-9_]集合中的一系列一个或多个(+)字符,表示任意小写(a-z)、大写(A-Z),或数字 (0-9) 字符以及下划线 (_)。

    最后一个子句是$,在这种情况下,它只是表示字符串的结尾。

    也就是说,您确实应该尽可能少地使用正则表达式。我个人建议通过设置交叉点来解决这个问题。

    import string
    # First, define all the acceptable characters
    acceptable = set(string.ascii_letters + string.digits + '_'))
    def is_valid(username):
        return len(username) >= 5 and set(username).issubset(acceptable)
    

    我喜欢这种方法的原因是因为正则表达式通常是一种非常脆弱且通常很慢的方法。原以为会慢一些,结果发现这里的正则表达式解决方案其实比 set 方法快很多(大约是 2.5 倍),但我还是觉得 set 代码的灵活性和可维护性让它更好整体解决方案。

    然而,看看 Blender 的解决方案,虽然它在解决这两个问题时并没有那么灵活。完全可读,实际上比正则表达式解决方案快三倍。

    为方便起见,发布了 Blender 的解决方案:

    def is_valid(username):
        return len(username) >= 5 and username.replace('_', '').isalpha()
    

    【讨论】:

    • 为什么必须尽可能少地使用正则表达式?
    • @VineetKaushik 正则表达式经常匹配您不期望的内容,并以奇怪的方式中断。更不用说编辑它来做非常直观的事情可能会很麻烦。
    • 我明白你的意思。顺便说一句,网站给出的正则表达式和这个有什么区别:^\w+$。这是我在解决方案中使用的正则表达式,根据网站,这是错误的。
    • @VineetKaushik 正则表达式脆弱的另一个例子。 python 中没有真正的区别,但\w 的定义实际上在实现之间发生了变化。在某些正则表达式中,例如 _ 不包含在 \w 集合中。
    • @Jerry Vim 正则表达式就是一个例子,但一般来说,如果正则表达式不是基于 Perl 的正则表达式(诚然这些往往是非常小众的),则不包括 _ 字符。在专有案件中相当普遍。 MATLAB 的 \w 最近才添加了 _ 字符,我相信 LabView 仍然缺少它。
    【解决方案3】:

    您的正则表达式执行以下操作

    ^ 断言位置在字符串的开头

    [a-zA-Z0-9_] 这将匹配任何字母、数字或符号_

    由于+ 量词遵循上述字符类 ([...]),这意味着匹配字符类在 ONE 和 UNLIMITED 次之间,按需回馈(贪婪)

    $ 然后断言字符串末尾的位置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-06
      • 2011-04-20
      相关资源
      最近更新 更多