假设我们有一个像“2 <
4”
如何确定它是否包含任何这些扩展序列?
我在CPAN上找到了HTML :: Entities,但它没有提供'check'方法。
详细信息:修复'truncate'方法,以便不会像“2 &l
”那样留下损坏的字符串,而不是做不必要的工作。看起来应该是这样的
$s = HTML::Entities::decode_entities ($s) if $has_ext_chars;
$s = substr ($s, 0, $len - 3) . '...' if length $s > $len;
$s = HTML::Entities::encode_entities ($s, "‚„-‰‹‘-™›\xA0¤¦§©«-®°-±µ-·»") if $has_ext_chars;
如何确定$ has_ext_chars?
答案 0 :(得分:1)
可以在the W3C reference上找到完整的字符实体列表。
您还必须匹配\&#u?\d+;
和\&#x[a-fA-F0-9]+;
答案 1 :(得分:1)
来自perldoc HTML::Entities:
该模块还可以导出 %char2entity和%entity2char 哈希,包含从所有字符到的字符的映射 相应的实体(反之亦然)。
您可以使用它们来构建正则表达式。例如,匹配实体:
use HTML::Entities '%entity2char';
my $regex = "&(?:" . join("|", map {s/;\z//; $_} keys %entity2char) . ");";
if ($str =~ /$regex/) {
print "$str contains entities\n";
}
这会跳过像&#entity_number;
这样的实体。
答案 2 :(得分:0)
您可以使用正则表达式
进行尝试$str =~ /.*\&[^\s]+;.*/
答案 3 :(得分:0)
从您的代码示例中,您可能刚刚在您的应用程序中引入了跨站点脚本攻击。如果我要让您的代码处理<script src="evil.example.com"></script>
之类的代码,您的代码会将其解码为有效的HTML,而不是将<
和>
重新编码回实体。 (代码中的尖括号不是ASCII尖括号。)
如果要截断包含任何HTML标记或实体的字符串,如果使用简单的解决方案,则可能会破坏某些内容。您可能最好基于HTML解析模块构建解决方案。如果您只查看元素内部没有元素的文本,则可以获取文本,截断文本然后将其替换回元素。如果你必须处理混合内容,那将会更复杂。
但是为了解决不好的问题:
#treats each entity as one character "2 < 4" is 5 characters long
$trunc_len = $len - 3;
$str =~ s/^((?>(?:[^&]|&[^\s;]+;?){$trunc_len}))(?:[^&]|&[^\s;]+;?){4,}/$1.../;
#abuses proceadural nature of the regexp engine
#treats each input character as on character "2 < 4" is 8 characters long
$str =~ s/^( (?:[^&]|&[^\s;]+;?)+ )(?(?{ $found = (pos() > ( $found ? $len - 3 : $len ))})(?!)).*$(?(?{pos() < $len })(?!))/$1.../x;
两者在允许常见浏览器怪癖的实体中相当宽容。