Regex nginx在重写到存在的url后返回404

Regex nginx在重写到存在的url后返回404,regex,url-rewriting,nginx,rewrite,Regex,Url Rewriting,Nginx,Rewrite,我已经在这上面敲了一段时间了,但是有人能帮我弄清楚为什么我的位置/块中的这个不匹配http://chrisbenard.net/wp-content/uploads/2010/12/chromeosalbum.png 它正在匹配和重定向http://chrisbenard.net/wp-content/uploads/2010/12/至http://chrisbenard.net/assets/uploads/2010/12/ location ~* \.(?:ico|svg|css|js|gi

我已经在这上面敲了一段时间了,但是有人能帮我弄清楚为什么我的
位置/
块中的这个不匹配
http://chrisbenard.net/wp-content/uploads/2010/12/chromeosalbum.png

它正在匹配和重定向
http://chrisbenard.net/wp-content/uploads/2010/12/
http://chrisbenard.net/assets/uploads/2010/12/

location ~* \.(?:ico|svg|css|js|gif|jpe?g|png)$ {
    if (-e $request_filename) {
        expires 3d;
        add_header Pragma public;
        add_header Cache-Control "public";
    }

    if (!-e $request_filename){
        rewrite "^/wp\-content/uploads/(.+)?" /assets/uploads/$1 permanent;
    }
    if (!-e $request_filename){
        rewrite ^/images/(.*)? /assets/images/$1 permanent;
    }
}
文件显然位于正确的目录中。此问题扩展到该目录下的所有文件

if (!-e $request_filename){
  rewrite ^/wp\-content/uploads/(.+)? /assets/uploads/$1 permanent;
}
另外,我想转到
/search/#query=query
。我试过:

rewrite ^/\?s\=(.*)$ /search/#?query=$1;
那一个也没用。我所有其他的正则表达式替换都很好。我已经从wordpress安装迁移到PieCrupt,这就是为什么我需要执行所有这些重定向

我用
(.*)
(.*)
(.+)
)和其他一些变体尝试了第一个正则表达式。我甚至试着用
*内容
替换
wp \-content
,我想可能是逃逸出了什么乱子。我运气不好

Edit:同样,这个正则表达式在Apache中工作得很好(对于资产目录;我无法让搜索正则表达式工作)。我用的是:

RewriteBase /
...
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^wp\-content/uploads/(.*)? /assets/uploads/$1 [NC,R=301,L]
apache版本中没有前导的lash,因为它不像nginx中那样包含在字符串的开头。同样,除了这两条规则外,所有其他nginx规则都运行良好

提前谢谢

编辑2:结果表明,只有当重写目标存在时才会发生

例如,这会重定向到正确的url:

这不会重定向到正确的url,只返回404(但如果您将wp内容更改为资产,它将正常加载):

此块匹配并干扰:

location ~* \.(?:ico|svg|css|js|gif|jpe?g|png)$ {
    expires 3d;
    add_header Pragma public;
    add_header Cache-Control "public";
}
即使我做到了这一点,我仍然有一个问题:

location ~* \.(?:ico|svg|css|js|gif|jpe?g|png)$ {
    if (-e $request_filename) {
        expires 3d;
        add_header Pragma public;
        add_header Cache-Control "public";
    }
}
我最终只是在匹配的位置复制了我的一些重写规则,并且成功了,但我不明白为什么。我猜这只是最具体的匹配,因此它忽略了
location/
中的规则

location ~* \.(?:ico|svg|css|js|gif|jpe?g|png)$ {
    if (-e $request_filename) {
        expires 3d;
        add_header Pragma public;
        add_header Cache-Control "public";
    }

    if (!-e $request_filename){
        rewrite "^/wp\-content/uploads/(.+)?" /assets/uploads/$1 permanent;
    }
    if (!-e $request_filename){
        rewrite ^/images/(.*)? /assets/images/$1 permanent;
    }
}

我认为您需要从
wp \-content
中删除连字符。我刚刚用alias试用过,它对我很有用:
location~ ^/wp content/uploads/(*){alias/your/absolute/path/here/assets/uploads/$1;}
。为了获得更好的性能,最好避免测试文件是否存在。或者尝试以下操作:
location~^/wp content/uploads/(.*){rewrite^/wp content/uploads/(.+)/assets/uploads/$1 permanent;}
我不想使用别名,因为我想要永久重定向。第二种方法可能有效,但我无法将图像的标题设置与重写结合起来。我不得不复制规则(或者我猜只是移动它们),因为我在下面的答案中发布了这些规则。所以在2天内我不会接受我的答案。你可以直接在
location
块中使用
add_header
。基本上,问题是我不能指定
location
块仅用于存在的文件。