求正则高手帮忙解决一个正则表达式的问题

2016-04-25 09:32:01 +08:00
 ZiShuo
由于最近流量暴涨,以前的老站后台没有设置静态文件的 CDN 接口。于是就想在入口文件加入一个用正则替换的静态文件的功能。自己参照网上写了下面的替换函数,能够解决大部分的静态文件,但是一旦遇上了以 http 、 https 或者 //开头的数据的数据就出错了。我知道咱站里面的技术大牛多,所以想请大牛们帮我下面这个函数改成能够除非以 http 、 https 或者 //开头的数据,也是排除原来本身就引用了外链的部分。

另外不要让我用全站 CDN 加速,因为业务限制,不太方便。我只想把特定后缀的文件的流量转移到 CDN 上面去。

function cdn_replace($html){
$cdnurl = "http://www.zishuo.net/"; //cdn Url
$exts = 'jpg|jpeg|gif|png|bmp|webp|css|js'; //扩展名(使用|分隔)
$regex = '/([^\s\?\\\'\"\;\>\<]{1,}.(' . $exts . '))([\"\\\'\s\?]{1})/';
$content = preg_replace($regex, $cdnurl. '$1$3', $html);
return $content;
}
3440 次点击
所在节点    PHP
15 条回复
thinkmore
2016-04-25 09:49:26 +08:00
能给出具体要求吗?比如说运行环境。原始文本。期望结果等。
比如: js
原始文本: http://www.baidu.com/show.html
期望文本: www.baidu.com/show.html (不获取协议头)
ango
2016-04-25 10:35:16 +08:00
前端外部资源,无非就这两类: href 、 src 。(周一脑子就像浆糊,是否还有其它实在想不起了)。
以这些标识开头,以指定 CDN 资源类型结尾, replace 一下就好了。
ango
2016-04-25 11:17:26 +08:00
@ango
$cdnUrl = 'http://www.zishuo.net/';
$exts = 'jpg|jpeg|gif|png|bmp|webp|css|js';
$pattern = "/((?:src|href)=[\"\']?)((?:http|https)?\/\/[^\/]+\/)(.+?\.(?:{$exts}))/";
//preg_match_all($pattern, $html, $matches);
$html = preg_replace($pattern, "\\1{$cdnUrl}\\3", $html);

另外,简单点可以用 preg_replace_callback 来处理的,简单正则找到要替换要位置后,用 callback 来判断一下是否需要处理。
jackal
2016-04-25 12:40:18 +08:00
我还算熟悉正则表达式。
但是对 PHP 不熟悉,对你的业务(想替换的文件是哪一些)也不熟悉。

我猜你想要的是找人帮你修改一下正则表达式,能更好地匹配。

麻烦你把规则说清楚,给一些例子,哪一些是匹配的,哪一些不需要匹配。

然后我们把修改好的正则表达式贴给你。
ZiShuo
2016-04-25 14:19:01 +08:00
@thinkmore
@ango
@jackal

是 PHP 的,举个例子吧?

我原本网页里面的图片地址是以下这种路径:

xxx/logo.jpg
/xxx/logo.jpg
./xxx/logo.jpg

现在我想将网页里面所有这种路径的都替换成下面这种 url :

http://www.zishuo.net/xxx/logo.jpg
ZiShuo
2016-04-25 14:19:53 +08:00
简单来说就是将
ZiShuo
2016-04-25 14:21:29 +08:00
简单来说就是将

<img alt="" src="index/a14.jpg" width="320" height="207" />
替换成
<img alt="" src="http://www.zishuo.net/index/a14.jpg" width="320" height="207" />

但是不仅仅限于图片,整个替换资源的类型为:

jpg|jpeg|gif|png|bmp|webp|css|js
imn1
2016-04-25 14:44:05 +08:00
感觉在 http sever 做 redir 跳转更简单些
./ 这种是相对路径,确定直接换成 CDN 的根?
ZiShuo
2016-04-25 16:10:36 +08:00
@imn1 基本上是可以确认我就是那三种路径,即使替换成 CDN 的根也是没影响的。我现在自己的那个替换函数是可以用的,但是要是存在 http 、 https 、//这种开头的外链路径就出错了,所我希望像 @jackal 说的一样,请人帮我修改一下正则表达式,能更好地匹配。排除以 http 、 https 或者 //开头的外链地址。
imn1
2016-04-25 16:16:32 +08:00
^(?!http|//).*jpg$
中间.*部分自己举一反三吧
cxbig
2016-04-25 16:24:50 +08:00
这种需求不应该 PHP 来做吧?在 Nginx 或 Apache 里写规则快多了。
thinkmore
2016-04-26 10:27:26 +08:00
((\.)?(/)?\w+/\w\.(jpg|jpeg|gif|png|bmp|webp|css|js))这个正则可以匹配你的资源。然后你替换下就行了.

不满足的稍微调试下就行了
ZiShuo
2016-04-26 15:48:45 +08:00
@thinkmore 能帮忙写个完整的替换函数吗?我用你那么替换上去后什么都匹配不出来了。
jackal
2016-04-26 17:12:58 +08:00
我跟你 @ZiShuo 讲,需求要这样表达才算清楚明了, 请你确认一下,然后朋友们帮你出正则表达式和替换了。
1 )资源一定是被“” ‘’(双引号,单引号)来包围括起来的
2 )资源结尾是 .(jpg|jpeg|gif|png|bmp|webp|css|js) ()括起来是限定“或者“的范围
3 )文件名肯定是 x/y.jpg 等 , x,y 可以是 1 个或者多个字符, x 表示目录名, x 可能是为空(没有目录,直接 y.jpg )或者多重目录(x/y/z.jpg 这样的)
字符的话, 是大小写字母和数字和-_(横杠和下划线)字符
4 )资源的协议,有可能是无协议,比如只是 src="index/a14.jpg";
但是也有可能是 http://www.abc.com/index/a14.jpg (请你考虑好这种情况的可能性,没有的话最好)
thinkmore
2016-04-27 09:54:34 +08:00
@ZiShuo 我不会写 php 的。我给你写了一个 js 版本的。你根据你的语法进行具体转换下吧

result = http://www.baidu.com/abc/test.do.replace(/\.?\/?(\w+\/\w+\.(jpg|jpeg|gif|png|bmp|webp|css|js))/mg, "http://www.zishuo.net/$1");

http://www.baidu.com/abc/test.do 换成你的匹配串就行了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/274153

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX