【发布时间】:2017-07-12 20:59:43
【问题描述】:
我正在编写一个 PHP 路由器引擎进行练习,目前正在为它做正则表达式。
映射的 URL 可以具有参数模式,并且可以像 {type:varName} 一样写下来。我不想让变量名多次出现,在这种情况下是varName。
我目前有这个正则表达式:
{(?<key>[a-zA-Z]{1,4}):(?<name>[a-zA-Z_]\w*\b)(?!.*\1\b)}
问题在于它只检查<key> 组中的重复项,而不检查<name> 组中的重复项。它还发现最后一个发生而不是找到的第一个。
如何使这个正则表达式只匹配<name> 组的第一次出现而不匹配第一次匹配的重复项?
示例
当你有这样的模式时:
{s:varName}-{i:varName}-{s:varName}
只有第一个 {s:varName} 应该匹配,其他 2 个不应该匹配。
当有这样的模式时:
{i:varName1}-{d:varName1}-{i:varName2}-{i:varName3}-{m:varName3}
{i:varName1}、{i:varName2} 和 {i:varName3} 应该匹配。
更新
感谢@sln,我最终得到了这个正则表达式:
{(?<key>[a-zA-Z]{1,4}):(?<name>[a-zA-Z_]+\b)}(?:(?!.*{[a-zA-Z_]{1,4}:\2))
唯一的问题是它与第一次出现的不匹配,而是与找到的最新匹配。
我在这里做错了什么?
【问题讨论】:
-
不要进行全局搜索,只进行搜索。这只会找到第一个。名称组中的重复是什么意思?
{(?<key>[a-zA-Z]{1,4}):(?<name>[a-zA-Z_]\w*\b)}(?!.*{\1:\2}) -
我所说的名称组中的重复是指
<key>组可以有多个i,但<name> 组不能有多个varName.全局搜索是什么意思? -
我很困惑,例如,不可能有这样的模式:
{s:varName}-{i:varName}-{s:varName},但允许这样的模式:{i:varName1}-{i:varName2}-{i:varName3} -
我刚刚给了你正则表达式
{(?<key>[a-zA-Z]{1,4}):(?<name>[a-zA-Z_]\w*\b)}(?!.*{\1:\2}) -
@sln 仍然匹配
<name>组的重复项:regex101.com/r/H4cuDJ/1