验证自定义格式的正则表达式

3
我有这种格式:xx:xx:xxxx:xx:xx-y,其中x可以是0-9 a-f A-F,y只能是0或1。
我得到了这个正则表达式:([0-9A-Fa-f]{2}[:][0-9A-Fa-f]{2}[:][0-9A-Fa-f]{2}|[-][0-1]{1}) (请参见regexr)。
但是这会匹配0a:0b:0c-3,这不是期望的结果。
有没有办法从结果中删除这些情况?

[0-1]更改为[01] - 9769953
1
[:] 表示一个只包含 : 的列表中的字符。它与 : 相同。同样,[-] 的结果与 - 相同。 - axiac
1
regex标签信息中可以得知:"由于正则表达式并没有完全标准化,所有带有此标签的问题也应包括指定适用的编程语言或工具的标签。" - Toto
2个回答

2

[:]代表一个只包含:的列表中的字符。它与:相同。[-]也是如此,其结果与-相同。
另外,{1}表示“前一个部分恰好出现一次”。它没有任何影响,您可以完全删除它。

为了匹配xx:xx:xxxx:xx:xx-y,匹配-y的部分必须是可选的。可选部分后面的量词符?将其标记为可选。

总之,您的regex应该像这样:

[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}(-[01])?

如果你使用的正则表达式引擎可以忽略字符大小写,那么你可以从所有字符类中去掉 A-F(或a-f),这样正则表达式就变成了:
[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}(-[01])?

它是如何工作的,逐个部分解析:

[0-9a-f]      # any digit or letter from (and including) 'a' to 'f'
{2}           # the previous piece exactly 2 times
:             # the character ':'
[0-9a-f]
{2}
:
[0-9a-f]
{2}
(             # start a group; it does not match anything
  -           # the character '-'
  [01]        # any character from the class (i.e. '0' or '1')
)             # end of group; the group is needed for the next quantifier
?             # the previous piece (i.e. the group) is optional
              # it can appear zero or one times

在实际应用中查看:https://regexr.com/4rfvr

更新

@the-fourth-bird在评论中提到,如果regex必须匹配整个字符串,则需要锚定其末尾:

^[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}(-[01])?$
regex 中的第一个字符 ^ 匹配字符串的开头,最后一个字符 $ 匹配字符串的结尾。这样,regex 只匹配整个字符串(当 xx:xx:xxxx:xx:xx-y 的前面或后面没有其他字符时)。
如果你在更大的字符串中使用 regex 查找 xx:xx:xxxx:xx:xx-y,则不需要添加 ^$。当然,你也可以只添加 ^$,使 regex 仅在字符串开头或结尾匹配。

2
不确定 OP 想要什么,但如果字符串不应该部分匹配而是完全不匹配,您还可以添加锚点 ^$。+1 - The fourth bird
@axiac感谢您详细的解释,但是建议的正则表达式仍然匹配了意外的字符串。nopole的建议在我的情况下有效。 - D.T

1
您希望:
如果时间格式为 xx:xx:xx,或者紧随其后的是 -,那么它必须是 01,然后就是结束(单词边界)。
因此,您不想要这些内容。
0a:0b:0c-123
0a:0b:0cd
10a:0b:0c

你需要"负向先行断言",所以如果匹配到第一部分,你不希望它后面跟着一个-(第一个模式),并且应该在那里结束(单词边界),如果它后面跟着一个-,那么它必须是01,然后再加上一个单词边界:

/\b([0-9a-f]{2}[:][0-9a-f]{2}[:][0-9a-f]{2}(?!-)\b|\b[0-9a-f]{2}[:][0-9a-f]{2}[:][0-9a-f]{2}-[01]\b)/i

为了防止任何数字出现在前面,我们还需要在前面加上一个单词边界。
例如:https://regexr.com/4rg42 以下几乎可以工作:
/\b([0-9a-f]{2}[:][0-9a-f]{2}[:][0-9a-f]{2}\b[^-]|\b[0-9a-f]{2}[:][0-9a-f]{2}[:][0-9a-f]{2}-[01]\b)/i

但是如果它是文件末尾且为“3a:2b:11”,那么“ [^-] ”将尝试匹配非“ - ”字符,但不会匹配。
示例:https://regexr.com/4rg4q

太棒了 @nopole 我想我缺少负面的向前查看,它完美地运行。 - D.T

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