# Package Lingua::DetectCharset # Version 1.02 # Part of "WWW Cyrillic Encoding Suite" # Get docs and newest version from # http://www.neystadt.org/cyrillic/ # # Copyright (c) 1997-98, John Neystadt # You may install this script on your web site for free # To obtain permision for redistribution or any other usage # contact john@neystadt.org. # # Portions copyright by # # Drop me a line if you deploy this script on tyour site. package Lingua::DetectCharset; $VERSION = "1.02"; use Convert::Cyrillic; use Lingua::DetectCharset::StatKoi; use Lingua::DetectCharset::StatWin; use Lingua::DetectCharset::StatUtf8; $PairSize = 2; $MinRatio = 1.5; # Mark must be in $MinRatio times larger of # one encoding than another to decide upon, or ENG. $DoubtRatio = 1; $DoubtLog = 'DetectCharsetDoubt.txt'; sub Detect { my (@Data) = @_; my ($KoiMark) = GetCodeScore ('Koi', @Data); my ($WinMark) = GetCodeScore ('Win', @Data); my ($Utf8Mark) = GetCodeScore ('Utf8', @Data); # print STDERR "GetEncoding: Koi8 - $KoiMark, Win - $WinMark, Utf8 - $Utf8Mark\n"; $KoiRatio = $KoiMark/($WinMark+$Utf8Mark+1); $WinRatio = $WinMark/($KoiMark+$Utf8Mark+1); $Utf8Ratio = $Utf8Mark/($KoiMark+$WinMark+1); if ($DoubtLog) { if (($KoiRatio < $MinRatio && $KoiRatio > $DoubtRatio) || ($WinRatio < $MinRatio && $WinRatio > $DoubtRatio) || ($Utf8Ratio < $MinRatio && $Utf8Ratio > $DoubtRatio)) { open Log, ">>$DoubtLog"; print Log " Koi8 - $KoiMark, Win - $WinMark, Utf8 - $Utf8Mark\n", join ("\n", @Data), "\n\n"; close Log; } } return 'KOI8' if $KoiRatio > $WinRatio && $KoiRatio > $Utf8Ratio; # $MinRatio; return 'WIN' if $WinRatio > $Utf8Ratio; # We do english, only if no single cyrillic character were detected return 'UTF8' if $WinRatio + $KoiRatio + $Utf8Ratio > 0; return 'ENG'; } sub GetCodeScore { my ($Code, @Data) = @_; my ($Table); if ($Code eq 'Koi') { $Table = \%Lingua::DetectCharset::StatKoi::StatsTableKoi; } elsif ($Code eq 'Win') { $Table = \%Lingua::DetectCharset::StatWin::StatsTableWin; } elsif ($Code eq 'Utf8') { $Table = \%Lingua::DetectCharset::StatUtf8::StatsTableUtf8Long; } else { die "Don't know $Code!\n"; } $PairSize = 4 if $Code eq 'Utf8'; $PairSize = 2 if $Code ne 'Utf8'; my ($Mark, $i); for (@Data) { s/[\n\r]//go; $_ = Convert::Cyrillic::toLower ($_, $Code); for (split (/[\.\,\-\s\:\;\?\!\'\"\(\)\d<>]+/o)) { for $i (0..length ()-$PairSize) { $Mark += ${$Table} {substr ($_, $i, $PairSize)}; } } } $Mark; } 1; __END__ =head1 NAME Lingua::DetectCharset - Routine for automatically detecting cyrillic charset. =head1 SYNOPSIS use Lingua::DetectCharset; $Charset = Lingua::DetectCharset::Detect ($Buffer); The returned $Charset is either 'WIN', 'KOI8', 'UTF8' or 'ENG'. The last is return when no single cyrillic token are found in buffer. =head1 DESCRIPTION This package implements routine for detection charset of the given text snippet. Snippet may contain anything from few words to many kilobytes of text, and may have line breaks, English text and html tags embedded. This routine is implemented using algorithm of statistical analysis of text, which was proved to be very efficient and showed around B<99.98% acccuracy> in tests. =head1 AUTHOR John Neystadt Portions by M@kr =head1 SEE ALSO perl(1), Convert::Cyrillic(3). =head1 NOTES Part of "WWW Cyrillic Encoding Suite" Get docs and newest version from http://www.neystadt.org/cyrillic/ Copyright (c) 1997-98, John Neystadt You may install this script on your web site for free To obtain permision for redistribution or any other usage contact john@neystadt.org. Drop me a line if you deploy this script on your site. =cut