匹配单词的第一次出现并忽略命名组

时间:2017-02-22 17:01:00

标签: php regex

我正在为练习编写一个PHP路由器引擎,我正在为它做正则表达式。

映射的URL可以包含参数模式,并像{type:varName}一样写下来。我不想允许变量名称出现多次出现,在这种情况下为varName

我现在有这个正则表达式:

{(?<key>[a-zA-Z]{1,4}):(?<name>[a-zA-Z_]\w*\b)(?!.*\1\b)}

(live version here)

问题是它只检查<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))

唯一的问题是,它与第一次出现并不匹配,但发现的是最新出现的。

我在这里做错了什么?

1 个答案:

答案 0 :(得分:0)

您可以采取解决方法。设置代理名称(多组,无重复),并在代码中获得所需的内容。

如果要使用正则表达式:

{s:varName}-{i:varName}-{s:varName}

写出:

{s:varName-1}-{i:varName-2}-{s:varName-3}

并编写一些逻辑:

  • 获取varName-*varName-1varName-2varName-3)的所有组,
  • 获取所需的内容(例如,首先出现varName-1)。

对于此正则表达式:

{i:varName1}-{d:varName1}-{i:varName2}-{i:varName3}-{m:varName3}

写:

{i:varName1-1}-{d:varName1-2}-{i:varName2-1}-{i:varName3-1}-{m:varName3-2}

和同样的逻辑:

  • 获取varName1-*varName1-1varName1-2),varName2-*varName3-*等的所有组。
  • 从所有多个组(*-1varName1-1varName2-1)中获取varName3-1

我使用此替代方法,因为某些其他语言(例如Java)不支持重复的组名。