【问题标题】:Regex for [a-zA-Z0-9\-] with dashes allowed in between but not at the start or end[a-zA-Z0-9\-] 的正则表达式,中间允许使用破折号,但不能在开头或结尾
【发布时间】:2011-02-01 06:59:36
【问题描述】:

更新:

这个问题是一个史诗般的失败,但这是有效的解决方案。它基于 Gumbo 的回答(Gumbo 已经接近工作,所以我选择它作为接受的答案):

解决办法:

r'(?=[a-zA-Z0-9\-]{4,25}$)^[a-zA-Z0-9]+(\-[a-zA-Z0-9]+)*$'

原始问题(尽管经过 3 次修改)

我正在使用 Python,我不是试图提取值,而是测试以确保它符合模式。

允许值:

spam123-spam-eggs-eggs1
spam123-eggs123
spam
1234
eggs123

不允许的值:

eggs1-
-spam123
spam--spam

我只是不能在开始或结束时使用破折号。 a question on here 通过事后获取字符串值以相反的方向工作,但我只需要测试该值以便我可以禁止它。此外,它可以最长为 25 个字符,但最少为 4 个字符。此外,没有两个破折号可以相互接触

这是我在进行了一些后视等实验后得出的结论:

# Nothing here

【问题讨论】:

  • 您介意在发布之前实际完成您的答案吗?在人们开始回答您的问题后继续添加限制条件(最少 4 个字符,最多 25 个字符)是不礼貌的。
  • 您提到至少 4 个字符,但在您的示例中,您将“123”作为允许值。应该在不允许的列中吗?
  • 您的描述中没有任何地方说您只想允许字母、数字和破折号。此外,您一直在更改问题。有人应该如何回答这个问题而不投反对票?
  • 最后的[a-zA-Z0-9]+不是必须的; (\-[a-zA-Z0-9]+)* 已经在报道了。
  • @Gumbo 谢谢,我误解了那部分,但现在我将其解读为(alnum 开头的任何破折号,以及此模式的零次或多次重复)。事实上,它不仅没有必要,而且实际上工作不正确。如果针对该 re 搜索字符串 i-am-string-number-5,它将返回 None,因为只有足够的内容可以被正则表达式的连字符模式吃掉。谢谢你所有的帮助。我已经编辑了我的解决方案。

标签: python regex


【解决方案1】:

试试这个正则表达式:

^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$

此正则表达式只允许用连字符分隔[a-zA-Z0-9] 的一个或多个字符的序列。


编辑    跟进您的评论:表达式(…)* 允许组内的部分重复零次或多次。这意味着

a(bc)*

一样
a|abc|abcbc|abcbcbc|abcbcbcbc|…

编辑    现在您更改了要求:由于您可能不想限制每个连字符分隔的单词部分的长度,您需要 look-ahead assertion 将长度变为帐号:

(?=[a-zA-Z0-9-]{4,25}$)^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$

【讨论】:

  • 比我快 24 秒!另外:您不允许连续破折号,并忽略 OP 要求的 {4,25} 长度限制。 (我在第一次阅读这个问题时也错过了......)
  • @orokusaki:* 量词允许组内的部分 (…) 重复零次或多次。这意味着也不可能重复。
  • @ephemient:你没有错过它们,OP 稍后添加了它们。并且一直在添加东西(没有连续的破折号)。
  • @orokusaki:你从“任何用字母或破折号组成的东西,除了开头或结尾不能是破折号”开始。然后您添加了{4,25} 要求。然后你添加了“没有两个连续的破折号”。您最初的示例都没有显示您的添加。
  • @orokusaki:啊,你是对的,谢谢!但是,如果在字符类的开头或结尾使用连字符,并且根本不需要在字符类之外使用,则不需要转义连字符。
【解决方案2】:

当前的正则表达式简单易读。您是否考虑过使用普通的 Python 字符串处理工具应用其他约束,而不是让它变得冗长而复杂?

import re

def fits_pattern(string):
    if (4 <= len(string) <= 25 and
        "--" not in string and
        not string.startswith("-") and
        not string.endswith("-")):

        return re.match(r"[a-zA-Z0-9\-]", string)
    else:
        return None

【讨论】:

  • 使用 not-putting-it-in-the-regex 可能有点过火,但总体思路值得考虑。正如那句老话所说:有些人在遇到问题时会想“我知道,我会使用正则表达式”。现在他们有两个问题。
【解决方案3】:

应该是这样的:

^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$

您告诉它只查找一个字符,a-z、A-Z、0-9 或 -,这就是 [] 的作用。

因此,如果您执行[abc],您将只匹配“a”、“b”或“c”。不是“abc”

玩得开心。

【讨论】:

  • @jpabluz 我只将正则表达式放在标题中以显示允许的字符。我当然会使用 + 或 *,但我想演示允许使用哪些字符。
【解决方案4】:

如果您只是不想在结尾和开头使用破折号,请尝试^[^-].*?[^-]$

编辑:呸,你一直在改变它。

【讨论】:

  • @synic,只是为了澄清,但始终只允许在中间使用字母、数字和破折号。
  • 你的描述中仍然没有这样说。
  • 说句公道话,在title中一直这么说。诚然,这不是提出要求的最佳地点,但你有它......
猜你喜欢
  • 2019-12-17
  • 2015-01-07
  • 1970-01-01
  • 2020-12-11
  • 2021-11-09
  • 2010-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多