这些正则表达式正在扼杀我,无论我读什么,我都无法理解这个概念。
这是我的问题,我确信它非常容易解决。
[img:http://example.com/_data/025_img.jpg]
我想要的是用[{1}}标签更改[img:...]所在的位,并获得如下结果
<img>
我尝试了各种愚蠢的变化,这些变化并没有奏效。我并不感到惊讶。
修改 的
其他信息:
我的情况如下。
用户将图片上传到他们的个人资料
图像名称存储在db。
我正在使用Codeigniter并将textarea传递到视图中并进入controller-&gt;模型,在那里它由各种事物的助手进行消毒...... sql / quotes等.XSS也在CI上启用
然后我想扫描文本,看看用户在哪里有[img:...]标签并将其交换为<img src='http://example.com/_data/025_img.jpg' border='0' />
标签,并使用图片后跟文字呈现帖子。
因此,用户的实际输入将是
<img>
这就是我要求preg_replace而不是preg_match的原因。 preg_match不会使文本跟随图像。
答案 0 :(得分:4)
让我们先轻松一点。
/\[img:([^\]]+)\]/
那是:
[img:
]
]
通过preg_match
运行此操作,匹配数组中的元素1很可能是您可以轻松插入img
代码的图片网址。
但你不应该。不是马上。
首先,这是不安全的。我写这篇文章会发生什么?
[img:javascript:alert(document.cookie);]
Uhoh。这不会很好。
你可能想要确保用户声称的URL确实是一个URL。您可以通过调用parse_url
来尝试这样做。它将为您提供一系列URL组件。确保该东西具有域和路径,并通过HTTP或HTTPS提供。
好的,但是当用户输入 this 时会发生什么?
[img:http://www.example.com/foo.jpg" onmouseover="alert(document.cookie)"]
这是一个有效的... ish ...将被parse_url
成功解构的网址,并且可能会通过基本检查以确定格式良好。过滤掉空格和引号(单个和 double)将是一个很好的起点,但仍有许多事情需要担心。
底线是像这样的标记是XSS, or Cross-site scripting vulnerabilities中的向量。
您可以 通过htmlspecialchars
传递网址来缓解某些威胁。这至少会引用引号和括号,并且很难对那些照顾过的人感到讨厌。只要注意字符集的愚蠢,一些非UTF-8字符编码可以包含ASCII引号......
你可能想要使用真正的标记语言(即使它只是降价),而可能想要使用基于白名单的HTML过滤器,如{ {3}}结果。这将有助于保护您免受某种程度的精神错乱。
请记住,如果他们不出去接你,你只会偏执。网络上到处都是愚蠢的人,他们是恶意的,人们是如此恶毒,以至于它是愚蠢的。
答案 1 :(得分:2)
如果您不喜欢正则表达式,则不必使用它们。至少不是为了这个目的。
以下内容应该:
$in = "[img:http://example.com/_data/025_img.jpg]";
if (strpos($in, "[img:") === 0)
{
$in = "<img src='" . substr($in, 5, -1) . "' border='0' />";
}
echo $in;
然而,这将是正则表达式:
$in = "[img:http://example.com/_data/025_img.jpg]";
preg_match("~\[img\:(.*?)\]~", $in, $matches);
if ($matches)
{
echo "<img src='" . $matches[1] . "' border='0' />";
}
简短说明:
模式为:"~\[img\:(.*?)\]~"
我使用~
作为模式的分隔符。您的起始[
必须转义,因为它是正则表达式字符。 img
可以保持原样,:
必须再次转义。之后,任何角色都可以跟随:.*
- 问号是将选择变为“ungreedy”,否则,它将匹配到结尾。把它放在(大括号)中,因此它被标记为$matches
的输出。之后,再次关闭]
- 这就是全部。
更新:请参阅Gumbos评论,:
无需转义。
答案 2 :(得分:1)
正则表达式很难,但功能强大。我根本不是大师,所以不要认为这是最好的解决方案。
$regEx = '/\[img:http:\/\/[\w]{3,10}\.(com|org|us){1}[\w\/]{5,15}\.(jpg|png|gif){1}\]/i';
$string = 'someting before [img:http://example.com/_data/025_img.png], something after [img:http://example.org/_data/025_img.jpg] and end of the line EOL';
$pstring = $string;
$matches[0] = array();
preg_match_all($regEx, $string, $matches);
匹配数组如下:
Array
(
[0] => Array
(
[0] => [img:http://example.com/_data/025_img.png]
[1] => [img:http://example.org/_data/025_img.jpg]
)
[1] => Array
(
[0] => com
[1] => org
)
[2] => Array
(
[0] => png
[1] => jpg
)
)
好的,这里发生了什么:
/
- 开始regexpression
\[img:http:\/\/
- 每个字符串都必须以[img:http://
开头
[\w]{3,10}
- 比我预期的只有3到10个数字,字母和下划线,这是域名(尽管我不确定域必须包含下划线,因此优化的优点)
\.
- 点
(com|org|us){1}
- 其中一个人
[\w\/]{5,15}
- 从5到15行作为路径,请注意我包括/此处另外
\.
- 点
(jpg|png|gif){1}
- 其中一个人
\]
- 模式结束
/i
- 使其不区分大小写
preg_match_all找到给定字符串中的所有匹配项,从分支到括号中的其他子字符串匹配作为$matches
的第二和第三个元素,我不知道为什么,所以如果有人可以帮助理解这一点,我们将不胜感激。
接下来使用简单的字符串操作,我可以替换所有主菜
这样的事情:(注意没有if
声明,因为我在开头添加了空的$ matches [0],没有ifs
就活得更好:))
foreach ($matches[0] as $match) {
$img = str_replace(array('[img:',']'), array('<img src="', '" />'), $match);
$pstring = str_replace($match, $img, $pstring);
}
您可以使用正则表达式,根据需要使其变得简单或复杂。
输出 $pstring
someting before <img src="http://example.com/_data/025_img.png" />, something after <img src="http://example.org/_data/025_img.jpg" /> and end of the line EOL
这里是playground http://phpfiddle.org/main/code/bbu-e24
答案 3 :(得分:0)
<?php
$str = '[img:http://example.com/_data/025_img.jpg]';
$image = '<img src="'.str_replace(array("[img:","]"),"",$str).'" border="0">';
echo $image;?>