我想创建同时满足以下两个条件的代码。
如果文字包含任何网址,则该部分会自动转换为<a href ~ class='temp_class'>
链接。
将func1()
应用于文本上的html实体字符,但上述函数生成的某些部分除外。 (这是为了防止恶意脚本的攻击。)
所以我写了下面的代码:
<?php
function func1($text) //function like htmlspecialchars
{
$text = str_replace("&", "&", $text);
$text = str_replace("\"", """, $text);
$text = str_replace("'", "'", $text);
$text = str_replace("<", "<", $text);
$text = str_replace(">", ">", $text);
$text = str_replace(" ", " ", $text);
return $text;
}
function func2($text)
{
$text = func1($text);
$url_pattern = "(http|https):\/\/([a-zA-Z0-9.\/?&=%_+-@~:#$]+)";
$text = preg_replace("/(".$url_pattern.")/i", "<a href='\\1' target='_blank' class='temp_class'>\\1</a>", $text);
return $text;
}
$test_string ="hello universe! https://www.youtube.com/watch?v=test <iframe src='https://youtube.com/watch?v=good'></iframe> hello world.";
echo func2($test_string);
?>
然而,当我运行上面的代码时,应用“太广泛”。 换句话说,'https://www.~'(...)'~hello world'被视为'单个链接'。
我想要的是三件事:
<a href ~ class='temp_class'>
适用于https://www.youtube.com/watch?v=test
<a href ~ class='temp_class'>
适用于https://youtube.com/watch?v=good
<
,>
,'
,etc.
由func1()
进行了适当的转换。因此<iframe ~ ></iframe>
代码不起作用。
1和2无法正常运行。
我可以猜到为什么会这样。也许func1()
将<
,>
,etc.
转换为<
,>
,etc.
,因此{{1}中的正则表达式将它们解释为url的一部分。
我可以猜到为什么,但我现在不知道该怎么做。
我正在考虑向func2()
中的$url_pattern
添加一些字词,以排除func2()
或%nbsp;
等字符的解释。但是,如何用regexp表达这一点对我来说也是一个很大的障碍。
我花了很长时间来解决这个问题,但这很困难。请帮帮我。
如果有任何您无法理解的内容,请发表评论。
答案 0 :(得分:1)
问题是你的func1()
会转换
中的所有空格,因此当正则表达式查看结果时,它会看到中断 - 例如在"hello"
下一个字符之后是正则表达式中允许的&
。
在执行HTML转义之前,您应该运行URL捕获正则表达式,然后再进行HTML转义。
顺便说一句 - 请使用htmlspecialchars()
代替您自己的自定义功能 - 正如@tadman所说。这样做的一个主要优点是htmlspecialchars()
不会转换空格,因此不会遇到您描述的问题,而且 - 将空格转换为非中断空格通常不是一个好主意。
答案 1 :(得分:0)
我想你可以尝试一下。防范网址中的实体。
( https? ) # (1)
: //
( # (2 start)
(?:
(?!
(?i)
(?:
&
(?:
[a-z_:] [a-z\d_:.-]*
| (?:
\#
(?: [0-9]+ | x [0-9a-f]+ )
)
)
| % [a-z_:] [a-z\d_:.-]*
)
;
)
[a-zA-Z0-9./?&=%_+-@~:#$]
)+
) # (2 end)
腓
http://sandbox.onlinephpfunctions.com/code/0bba1854a960c00d4946b9cdaa9cca2ca2e447fc
<?php
function func1($text) //function like htmlspecialchars
{
$text = str_replace("&", "&", $text);
$text = str_replace("\"", """, $text);
$text = str_replace("'", "'", $text);
$text = str_replace("<", "<", $text);
$text = str_replace(">", ">", $text);
$text = str_replace(" ", " ", $text);
return $text;
}
function func2($text)
{
$text = func1($text);
$url_pattern = "(http|https):\/\/((?:(?!(?i)(?:&(?:[a-z_:][a-z\d_:.-]*|(?:\#(?:[0-9]+|x[0-9a-f]+)))|%[a-z_:][a-z\d_:.-]*);)[a-zA-Z0-9.\/?&=%_+-@~:#$])+)";
$text = preg_replace("/(".$url_pattern.")/i", "<a href='\\1' target='_blank' class='temp_class'>\\1</a>", $text);
return $text;
}
$test_string ="hello universe! https://www.youtube.com/watch?v=test <iframe src='https://youtube.com/watch?v=good'></iframe> hello world.";
echo func2($test_string);
输出(带有额外的换行符间距)
hello universe!
<a href='https://www.youtube.com/watch?v=test' target='_blank' class='temp_class'>
https://www.youtube.com/watch?v=test
</a>
<iframe src='
<a href='https://youtube.com/watch?v=good' target='_blank' class='temp_class'>
https://youtube.com/watch?v=good
</a>
'></iframe> hello world.