允许中间有连字符的[a-zA-Z0-9\-]正则表达式,但不能位于开头或结尾

10 投票
4 回答
32532 浏览
提问于 2025-04-15 20:54

更新:

这个问题真是个大失败,但这里有一个有效的解决方案。这个方案是基于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

我就是不想让字符串的开头或结尾有破折号。这里有一个相关的问题,它是通过获取字符串的值来处理的,但我只是想测试这个值,以便可以拒绝不符合的情况。此外,字符串最长不能超过25个字符,但最短要4个字符。还有,不能有两个破折号连在一起

这是我经过一些实验后,使用lookbehind等方法得出的结果:

# Nothing here

4 个回答

2

应该像这样:

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

你是在告诉它只找一个字符,可以是小写字母a到z,大写字母A到Z,数字0到9,或者是“-”,这就是方括号[]的作用。

所以如果你写 [abc],那么它只会匹配“a”、“b”或者“c”,而不会匹配“abc”。

祝你玩得开心。

4

现在这个正则表达式简单且比较容易理解。与其把它弄得又长又复杂,不如考虑用普通的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
17

试试这个正则表达式:

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

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


编辑    关于你提到的评论:表达式 (…)* 允许括号内的部分重复零次或多次。这意味着

a(bc)*

和下面这个是一样的:

a|abc|abcbc|abcbcbc|abcbcbcbc|…

编辑    现在你改变了要求:因为你可能不想限制每个用连字符分隔的部分的长度,所以你需要一个 前瞻断言 来考虑长度的问题:

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

撰写回答