Perl 如何检查HTML是否包含扩展实体,如&;书信电报;?

Perl 如何检查HTML是否包含扩展实体,如&;书信电报;?,perl,Perl,假设我们有一个类似“24”的html字符串 如何确定它是否包含这些扩展序列 我在CPAN上找到了HTML::Entities,但它没有提供“检查”方法 详细信息:修复“truncate”方法时,不要像“2&l”那样留下损坏的字符串,也不要做不必要的工作。应该是这样的 $s = HTML::Entities::decode_entities ($s) if $has_ext_chars; $s = substr ($s, 0, $len - 3) . '...' if length $s >

假设我们有一个类似“2
4”的html字符串

如何确定它是否包含这些扩展序列

我在CPAN上找到了HTML::Entities,但它没有提供“检查”方法

详细信息:修复“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\u ext\u chars?

您可以使用正则表达式进行尝试

$str =~ /.*\&[^\s]+;.*/

可以在上找到角色实体的完整列表

您还必须匹配
\&#u?\d+
\&#x[a-fA-F0-9]+

来自perldoc:

该模块还可以导出 %Char2实体和%entity2char 哈希,它包含从所有字符到 相应实体(反之亦然)

您可能可以使用它们来构建正则表达式。例如,要匹配实体,请执行以下操作:

use HTML::Entities '%entity2char';

my $regex = "&(?:" . join("|", map {s/;\z//; $_} keys %entity2char) . ");";

if ($str =~ /$regex/) {
    print "$str contains entities\n";
}

这将跳过像
和#entity_number但是。

从代码示例中,您可能刚刚在应用程序中引入了跨站点脚本攻击。如果我让您的代码处理类似于
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;
#将每个实体视为一个字符“2 4”为5个字符长
$trunc_len=$len-3;
$str=~s/^((?>(?:[^&]|和[^\s;]+;?){$trunc_len})(?:[^&]|和[^\s;]+;?){4,}/$1./;
#regexp引擎的原始性质
#将每个输入字符视为“2 4”上的字符长度为8个字符
$str=~s/^((?:[^&]|&[^\s;]+;)+(?({$find=(pos()>($find?$len-3:$len))})(?!).$(?(?{pos()<$len})(?!)/$1…/x;

这两个实体都非常允许出现常见的浏览器怪癖。

使用
添加数字实体非常容易|#[0-9]+' . '|#x[0-9a-fA-F]+'