【问题标题】:Python regex: string does not contain "jpg" and must have "-" and lowercasePython正则表达式:字符串不包含“jpg”,必须有“-”和小写
【发布时间】:2011-05-05 18:39:17
【问题描述】:

我在为 django url 找出 python 正则表达式时遇到了麻烦。我有一定的标准,但似乎无法想出神奇的公式。最后,我可以识别哪个页面是 CMS 页面,并将它应该加载的别名 url 传递给 django 函数。

以下是一些可以匹配的有效字符串示例:

  • 关于我们
  • 联系我们
  • 条款和条件
  • info/learn-more-pg2
  • info/my-example-url

标准:

  • 必须全部小写
  • 必须包含破折号“-”
  • 可以包含数字、字母和斜线“/”
  • 长度必须至少为 4 个字符,最多 30 个字符
  • 不能包含特殊字符
  • 不能包含以下词语:
    • .jpg
    • .gif
    • .png
    • .css
    • .js

不应匹配的示例:

  • 关于我们(有大写字母)
  • 联系我们(没有破折号)
  • pg(少于 4 个字符)
  • img/bg.gif(包含“.gif”)
  • files/my-styles.css(包含“.css”)
  • my-page@(包含字母、数字、破折号或斜线以外的字符)

我知道这还不是很接近,但这是我所知道的:

(?P<alias>([a-z/-]{4,30}))

我很抱歉有很大的要求,但我就是无法理解这个正则表达式的东西。

谢谢!

【问题讨论】:

  • 嗯,您要求的一些事情,例如计算字符数,在正则表达式中本来就很难做到。另外,我的理解是网址不区分大小写。 (至少,每当我访问网站并使用大写字母时,我都会到达并且它们都是小写数字。)此外,测试 是否存在“.gif”和喜欢而不是否定它。你能不能先给他们制定一条规则,在到达这条规则之前过滤掉里面有它们的url?
  • 我有另一个 URL 结构,它只包含没有斜杠或破折号的大写字符,并且所有 CMS 页面都是带有破折号的小写字母。此外,长度不是优先事项,如果它不能完成或者它是性能猪,我可以放弃它。
  • @Tyr:如何在正则表达式中计算字符数?如果您使用的是 Apache(我认为),URL 也不不区分大小写,至少不是域之后的部分。
  • 好吧,我承认我对 Apache 如何处理 url 知之甚少,你可能是对的。我的意思是,正则表达式不能算多于一件事。 (什么正则表达式以任何顺序匹配具有相同数量“a”和“b”的所有字符串?)

标签: python regex django django-urls


【解决方案1】:

我很困惑为什么一些评​​论员发现在正则表达式中很难做到这一点。这正是正则表达式所擅长的。

if re.match(
    r"""^             # match start of the string
    (?=.*-)           # assert that there is a dash
    (?!.*\.(?:jpg|gif|png|css|js))  # assert that these words can't be matched
    [a-z0-9/-]{4,30}  # match 4-30 of the allowed characters
    $                 # match the end of the string""", 
    subject, re.VERBOSE):
    # Successful match at the start of the string
else:
    # Match attempt failed

不过,由于. 不在允许的字符范围内,因此确实不需要检查被禁止的文件扩展名。

【讨论】:

  • +1 该死,正则表达式又做了一次 :) 我一直忘记前瞻。 (但是当您要使用 .match 时,您可以删除 ^ 并且最外面的括号可能不平衡,因为最后一个括号在评论中;为什么您在整个正则表达式上使用非分组?)。
  • 或者,如果不使用单一的整体正则表达式,使用更少的 cmets 可能会更具可读性:-)
  • @delnan:你在这两个方面都是对的。括号是以前版本的遗留物,我现在已经删除了它们。 ^ 确实是不必要的,但因为它不会造成伤害并且意图更清晰,所以我把它留在了。
【解决方案2】:

这是我关于 SO 的第一篇文章。 Pleeaaase,请在需要时纠正我的英语,我确实要求您。

我认为以下任何一个 RE 都适合:

'(?=.{4,30}\Z)(?=.*-)[-a-z0-9/]+\Z'

'(?=.{4,30}\Z)[a-z0-9/]\*-[-a-z0-9/]\*\Z'

'(?=.{4,30}\Z)(?:[a-z0-9/]+|)-[-a-z0-9/]*\Z'

【讨论】:

    猜你喜欢
    • 2019-10-07
    • 1970-01-01
    • 2015-05-12
    • 2011-05-02
    • 2011-11-30
    • 2019-09-15
    • 2018-09-17
    • 2012-08-05
    • 2011-07-22
    相关资源
    最近更新 更多