Created
January 16, 2011 14:29
-
-
Save creaktive/781832 to your computer and use it in GitHub Desktop.
encodingless HTML text extractor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
use strict; | |
# Para ter certeza absoluta de que nenhum warning de 'Wide character' escapou | |
use warnings 'all'; | |
# Somente indica que este arquivo .pl está na codificação UTF-8!!! | |
use utf8; | |
# Ignora codificação de entrada | |
use open IN => ':bytes'; | |
# Usa a codificação de saída padrão do sistema | |
use open OUT => ':locale'; | |
use Encode; | |
use HTML::Entities; | |
use Regexp::Common qw(balanced comment); | |
# Lê arquivo inteiro de uma vez, ao invés de ler linha por linha | |
local $/ = undef; | |
while (my $buf = <>) { | |
# Se não for UTF-8 válido, assume ISO-8859-1 | |
my $encoding = detect_utf8(\$buf) ? 'utf8' : 'iso-8859-1'; | |
# Processa a codificação | |
$buf = decode($encoding, $buf); | |
# Trata tags HTML | |
$buf =~ s%$RE{comment}{HTML}%%gos; | |
$buf =~ s%<(script|style)\b[^>]*?>.*?</\1>% %gis; | |
$buf =~ s%$RE{balanced}{-parens=>'<>'}% %gios; | |
$buf = decode_entities($buf); | |
# Extrai somente as palavras, normaliza e imprime | |
print "\L$1 " while $buf =~ m%([\w\-]+)%g; | |
} | |
print "\n"; | |
# detect_utf8(\$string) | |
# Recebe referência para escalar com string a ser analisada e retorna: | |
# 0 - $string tem caracteres de 8 bits, não valida como UTF-8; | |
# 1 - $string tem somente caracteres de 7 bits; | |
# 2 - $string tem caracteres de 8 bits, valida como UTF-8. | |
# Algoritmo original em PHP: http://www.php.net/manual/en/function.utf8-encode.php#85293 | |
# Fórmula da conversão: http://home.tiscali.nl/t876506/utf8tbl.html#algo | |
sub detect_utf8 { | |
use bytes; | |
my $str = shift; | |
my $d = 0; | |
my $c = 0; | |
my $b = 0; | |
my $bits = 0; | |
my $len = length ${$str}; | |
for (my $i = 0; $i < $len; $i++) { | |
$c = ord(substr(${$str}, $i, 1)); | |
if ($c >= 128) { | |
$d++; | |
if ($c >= 254) { | |
return 0; | |
} elsif ($c >= 252) { | |
$bits = 6; | |
} elsif ($c >= 248) { | |
$bits = 5; | |
} elsif ($c >= 240) { | |
$bits = 4; | |
} elsif ($c >= 224) { | |
$bits = 3; | |
} elsif ($c >= 192) { | |
$bits = 2; | |
} else { | |
return 0; | |
} | |
if (($i + $bits) > $len) { | |
return 0; | |
} | |
while ($bits > 1) { | |
$i++; | |
$b = ord(substr(${$str}, $i, 1)); | |
if (($b < 128) || ($b > 191)) { | |
return 0; | |
} | |
$bits--; | |
} | |
} | |
} | |
return $d ? 2 : 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment