不带文件扩展名的正则表达式匹配URL

6
我希望能够得到帮助,匹配以下URL链接。
/settings => /settings.php
/657_46hallo => /657_46hallo.php
/users/create => /users.php/create
/contact/create/user => /contact.php/create/user
/view/info.php => /view.php/info.php
/view/readme - now.txt => /view.php/readme - now.txt
/ => [NO MATCH]
/filename.php => /unknown.php
/filename.php/users/create => /unknown.php

如果域名后的第一部分是以".php"结尾的文件名(参见最后2个示例),则应重定向到/unknown.php。我认为需要2个正则表达式,第一个几乎应该是:^/([a-zA-Z0-9_]+)(/)?(.*)?$,第二个用于捕获直接文件名"/filename.php"或"/filename.php/create/user",以便可以重定向到unknown.php。我已经得到了几乎适用于第一部分的第一个正则表达式。==============================================
request url: http://domain.com/user/create
regex: ^/([a-zA-Z0-9_]+)(/)?(.*)?$
replace http://domain.com/$1.php$2$3
makes: http://domain.com/user.php/create

问题在于它还匹配了http://domain.com/user.php/create。 如果有人能帮我处理这两个正则表达式,那就太好了。
2个回答

1
如果你想匹配那些 .php 的情况,你可以尝试这个:
^\/([a-zA-Z0-9_]+)(\/)?(.*)?$

Regexr这里查看

如果你想避免这些情况,请尝试这个:

^/([a-zA-Z0-9_]+)(?!\.php)(?:(/)(.*)|)$

在这里查看 Regexr

(?!\.php) 是一个负向预查,确保此处没有 .php


那似乎能解决问题。(发布的第一个示例与regexr链接上的不同,但regexr网站上的那个是有效的:^/([a-zA-Z0-9_]+.php)(/)?(.*)?$) - Cecil Zorg

1

当你只拥有一把锤子时...

虽然这个问题可能可以通过正则表达式来解决,但除非你必须使用正则表达式,否则它可能不是最适合的工具。

使用“/”作为分隔符分割字符串,查看第一个组件是否以“.php”结尾;如果是,则拒绝它,否则在第一个组件末尾添加“.php”,最后使用“/”将组件连接起来。


1
这将被用作Cherokee Web服务器上的重写规则。Cherokee Web服务器不允许我拆分URL,编程语言确实会使它变得更容易,但不幸的是这不是一个选项。 - Cecil Zorg

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