正则表达式组匹配恰好n次

11

我需要验证下一个字符串的格式:

text-text-id-text

分隔符为“-”。第三列必须始终为ID。我编写了下面的正则表达式(在Python中),用于验证字符串:

分隔符为“-”,第三个字段必须是ID。我编写了以下Python正则表达式来验证字符串:

import re

s = 'col1-col2-col3-id' # any additional text at the end
                        # is allowed e.g. -col4-col5
print re.match('^(.*-){3}id(-.*)?$', s) # ok 
print re.match('^(.*-){1}id(-.*)?$', s) # still ok, is should not be

我尝试使用非贪婪模式,但结果仍然相同:

^(.*?-){1}id(-.*)?$

我的正则表达式有什么问题?我可以使用以下方式验证字符串:

>>> import re
>>> print re.split('-', 'col1-col2-col3-id')
['col1', 'col2', 'col3', 'id']

然后检查第三个元素是否与id匹配,但我对为什么第一个正则表达式如上所述有效很感兴趣。

1个回答

11

你的第一个正则表达式不正确,因为它断言在前三个项目之后存在id
你的第二个正则表达式匹配字符串不正确,因为.*也会匹配连字符。

你应该使用这个正则表达式:

/^(?:[^-]+-){2}id/

这里有一个正则表达式演示

如果你需要将正则表达式锚定到末尾,请使用/^(?:[^-]*-){2}id.*$/


Tim Pietzcker所述,考虑在项的末尾断言id

/^(?:[^-]+-){2}id(?![^-])/

这里是一个更新后的正则表达式演示


1
+1,并且可能在“id”后使用前瞻断言(?=-|$),以确保第三列不是类似于“idiom”的内容。 - Tim Pietzcker
可能是这样,但我们不知道在“-”之间允许哪些字符,也许“id.txt”是有效的,不应该被匹配。 - Tim Pietzcker
1
@Unihedron .* 匹配连字符也可以。谢谢你。 ?: 是必要的吗? - broadband
1
我现在明白 ?: 的含义了。请阅读 https://dev59.com/QXA75IYBdhLWcg3wBkS1。 - broadband
@broadband 很棒!也看看这个。 - Unihedron
显示剩余2条评论

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