简体   繁体   English

正则表达式匹配网址

[英]regex matching url

In PHP, the klein routing will match as many routes as it can. 在PHP中,klein路由将匹配尽可能多的路由。 2 routes I have set up are conflicting. 我设置的2条路线存在冲突。 They are: 他们是:

$route1: '/websites/[i:websiteId]/users/[i:id]?'

and

$route2: '/websites/[i:websiteId]/users/[a:filename].[json|csv:extension]?'

This is the URL I'm trying to match, which I think should match the first and not the second, is: 这是我要匹配的URL,我认为应该匹配第一个而不是第二个:

/api/v1-test/websites/100/users/4

The regex produced for these two are: 为这两个生成的正则表达式为:

$regex1: `^/api(?:/(v1|v1-test))/websites(?:/(?P<websiteId>[0-9]++))/users(?:/(?P<id>[0-9]++))?$`

$regex2: `^/api(?:/(v1|v1-test))/websites(?:/(?P<websiteId>[0-9]++))/users(?:/(?P<filename>[0-9A-Za-z]++))(?:\.(?P<extension>json|csv))?$`

I mean for it not to match if there is no '.csv' or '.json'. 我的意思是,如果没有“ .csv”或“ .json”,它就不匹配。 The problem is that it is matching both routes. 问题在于它同时匹配这两个路由。 For the second, the resulting filename is '4' and the extension is blank. 第二个结果文件名是“ 4”,扩展名是空白。

Sending /api/v1-test/websites/100/users/users.csv works correctly and only matches the second route. 发送/api/v1-test/websites/100/users/users.csv可以正常工作,并且仅与第二条路由匹配。

I only have control over the route, not the regex or the matching. 我只能控制路由,而不能控制正则表达式或匹配项。 Thanks. 谢谢。

This bit here 这一点

(?:\.(?P<extension>json|csv))?

at the end of your second regex causes it to match whether or not there's a filename due to the ? 在第二个正则表达式的末尾,使它匹配是否由于文件名而导致文件名? at the very end. 在最后。 Question marks mean 0 or 1 of the previous expression . 问号表示0 or 1 of the previous expression Get rid of that and, at the least, strings will only match this regex when they have the extension. 摆脱它,至少,字符串只有在具有扩展名时才匹配此正则表达式。

To make this change, just remove the question mark from your second route, like so: 要进行此更改,只需从第二条路线中删除问号,如下所示:

$route2: '/websites/[i:websiteId]/users/[a:filename].[json|csv:extension]'

The problem is that the match_type is defined really... weirdly: 问题是match_type确实定义了……很奇怪:

$match_types = array(
            'i' => '[0-9]++',
            'a' => '[0-9A-Za-z]++',
[...]

As such, you can't really capture a sequence corresponding to [a-zA-Z] only... The only option I see would be to use 3 routes: 因此,您无法真正捕获仅与[a-zA-Z]对应的序列...我看到的唯一选择是使用3条路线:

$route1: '/websites/[i:websiteId]/users/[i:id]?'
$route2: '/websites/[i:websiteId]/users/[a:filename]'
$route3: '/websites/[i:websiteId]/users/[a:filename].[json|csv:extension]'

And to assign the same actions for routes 2 and 3. Then you would have this: 并为路由2和3分配相同的操作,那么您将获得:

  • /api/v1-test/websites/100/users/ is matched by 1 /api/v1-test/websites/100/users/匹配为1
  • /api/v1-test/websites/100/users/4 is matched by 1 /api/v1-test/websites/100/users/4由1匹配
  • /api/v1-test/websites/100/users/test is matched by 2 /api/v1-test/websites/100/users/test由2匹配
  • /api/v1-test/websites/100/users/test.csv is matched by 3 /api/v1-test/websites/100/users/test.csv由3匹配

Which seems like the behavior you wanted. 这似乎是您想要的行为。

Abother (easier) solution would be to take advantage of this bit of the documentation: 另一个(更简单)的解决方案是利用文档的以下内容:

Routes automatically match the entire request URI.
If you need to match only a part of the request URI
or use a custom regular expression, use the @ operator.

You can then define your routes like this: 然后,您可以像这样定义路线:

$route1: '@/websites/[0-9]+/users/[0-9]*$'
$route1: '@/websites/[0-9]+/users/[a-zA-Z]+(\.[a-zA-Z]+)?$'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM