易码技术论坛

 找回密码
 加入易码
搜索
12
返回列表 发新帖
楼主: king

[求助] 求在C中将一个字符串中的汉字提取出来的算法

[复制链接]
发表于 2008-5-25 19:57:33 | 显示全部楼层

恶劣工作环境代码

用于从非文本内容中滤过出连续的类似文字的东西.
这样他要用就得自己改了吧, jason兄~~
  1. function TMainFrm.RipThreadExecute(Sender: PThread): Integer;
  2. var
  3.   Spos, Ssize, Dripd, crLenth, crByte, CrAddon: Int64;
  4.   Position0, Position1, Position2: Integer;
  5.   StartTick: DWORD;
  6.   B1, B2: Byte;
  7.   W1:     WORD;
  8.   mRipEng, mRipMix, mRipHan: Boolean;
  9.   mIsHan, Flush, Mixed: Boolean;
  10.   aEng, aHan: Boolean;
  11.   limEng, limHan, limMix: Integer;
  12.   RecPre, RecLine: String;
  13.   IsHan:  function(B1: Byte; B2: Byte): Boolean;
  14.   ExfHan: function(B1: Byte; B2: Byte): Boolean;
  15.   IsEng:  function(B: Byte): Boolean;
  16. begin
  17.   StartTick := GetTickCount();
  18.   mRipEng := RipEng.Checked;
  19.   mRipHan := RipHan.Checked;
  20.   mRipMix := RipMix.Checked;
  21.   LimEng  := MHLimEng.Position;
  22.   LimHan  := MHLimHan.Position;
  23.   LimMix  := MHLimMix.Position;

  24.   IsHan := nil;
  25.   if RipBig5.Checked then     IsHan := IsBIG5;
  26.   if RipGBK.Checked then      IsHan := IsGBK;
  27.   if RipGB2312.Checked then   IsHan := IsGB2312;
  28.   if RipJIS.Checked then      IsHan := IsJIS;
  29.   ExfHan := nil;
  30.   if ExfBig5.Checked then     ExfHan := IsBIG5;
  31.   if ExfGBK.Checked then      ExfHan := IsGBK;
  32.   if ExfGB2312.Checked then   ExfHan := IsGB2312;
  33.   if ExfJIS.Checked then      ExfHan := IsJIS;

  34.   if RipJIS.Checked then
  35.     IsEng := IsAsciiOrHalfWidthKatakana
  36.   else
  37.     IsEng := IsAscii;

  38.   if noWholeBuff.Checked then
  39.   begin
  40.     BufStm := NewReadFileStream(RipInputEdt.Text);
  41.     Ssize  := BufStm.Size;
  42.   end
  43.   else
  44.   begin
  45.     InputFStm := NewReadFileStream(RipInputEdt.Text);
  46.     BufStm    := NewMemoryStream();
  47.     Ssize     := InputFStm.Size;
  48.     BufStm.Size := Ssize;
  49.     Stream2Stream(BufStm, InputFStm, InputFStm.Size);
  50.     InputFStm.Free;
  51.     BufStm.Position := 0;
  52.   end;
  53.   StringStm := NewMemoryStream();
  54.   StringStm.Position := 0;
  55.   Spos      := 0;
  56.   Dripd     := 0;
  57.   Crlenth   := 0;
  58.   Crbyte    := 0;
  59.   CrAddon   := 0;
  60.   aEng      := False;
  61.   aHan      := False;
  62.   Flush     := False;
  63.   Mixed     := False;
  64.   RarProgressBar1.Position1 := 0;
  65.   RarProgressBar1.Position2 := 0;
  66.   OutputFStm := NewWriteFileStream(RipOutputEdt.Text);
  67.   OutputFStm.Size := 0; //ReWrite
  68.   while Spos <= Ssize do
  69.   begin
  70.     if CrLenth div 1024 >= StringStm.Size div 1024 then
  71.       StringStm.Size := (CrLenth div 1024) + 1024; //扩展字符缓冲
  72.     BufStm.Read(B1, 1);
  73.     Inc(Spos);
  74.     if IsEng(B1) then
  75.     begin
  76.       if mRipMix or mRipEng then
  77.       begin
  78.         aEng := True;
  79.         if aHan then
  80.         begin
  81.           Mixed := True;
  82.           aHan  := False;
  83.         end;
  84.         //写入单个Ascii
  85.         INC(CrAddon);
  86.         case B1 of
  87.           $09: StringStm.WriteStr('\t');
  88.           $0D: StringStm.WriteStr('\r');
  89.           $0A: StringStm.WriteStr('\n');
  90.         else
  91.           StringStm.Write(B1, 1);
  92.           Dec(CrAddon);
  93.         end;

  94.         Inc(CrLenth);
  95.         Inc(CrByte);
  96.       end//mripMixEng
  97.       else
  98.       begin
  99.         if crLenth > 0 then
  100.           Flush := True;
  101.       end;
  102.     end
  103.     else
  104.     begin
  105.       if (B1 in [$81..$FE]) then //EUC
  106.       begin
  107.         BufStm.Read(B2, 1);
  108.         Inc(Spos);
  109.         if mRipMix or mRipHan then
  110.           mIsHan := IsHan(B1, B2)
  111.         else
  112.           mIsHan := ExfHan(B1, B2);
  113.         if mIsHan then
  114.         begin
  115.           if mRipMix or mRipHan then
  116.           begin
  117.             aHan := True;
  118.             if aEng then
  119.             begin
  120.               Mixed := True;
  121.               aEng  := False;
  122.             end;
  123.             //写入一个汉字
  124.             W1 := (B2 SHL 8) + B1;
  125.             StringStm.Write(W1, 2);
  126.             Inc(CrLenth);
  127.             Inc(CrByte, 2);
  128.           end//mRipHan
  129.           else
  130.           begin//00
  131.             if crLenth > 0 then
  132.               Flush := True;
  133.           end;
  134.         end//isHan
  135.         else
  136.         begin
  137.           //回退字节
  138.           BufStm.Seek(-1, spCurrent);
  139.           Dec(Spos);
  140.           if CrLenth > 0 then
  141.             Flush := True;
  142.         end;//notisHan
  143.       end//preHan
  144.       else
  145.       begin
  146.         //低字节或者7F,FF
  147.         if (Crlenth > 0) {or (not(IsHalfWidthKatakana(B1)) and (RipJIS.Checked))} then
  148.           Flush := True;
  149.       end;//notprebig5
  150.     end;//isascii
  151.     if Spos >= SSize then//no Ssize-1 because not overflow
  152.     begin
  153.       Inc(Spos);
  154.       Flush := True;
  155.     end;
  156.     if Flush then
  157.     begin
  158.       if (Mixed and mRipMix and (Crlenth >= LimMix)) or (not (Mixed) and aEng and mRipEng and (Crlenth >= LimEng)) or
  159.         (not (Mixed) and aHan and mRipHan and (Crlenth >= LimHan)) then
  160.       begin
  161.         RecPre := Int2Hex(Spos - 1 - Crbyte, 8) + ',' + Int2Hex(Crbyte, 8) + ',';
  162.         OutputFStm.WriteStr(RecPre);
  163.         StringStm.Position := 0;
  164.         SetLength(RecLine, CrByte + CrAddon);
  165.         //Stream2Stream(OutputFStm, StringStm, CrByte);
  166.         StringStm.Read(PChar(RecLine)^, Length(RecLine));
  167.         //with StrReplace(RecLine, '\', '\\') do;
  168.         //while StrReplace(RecLine, #$0D, '\r') do;
  169.         //while StrReplace(RecLine, #$0A, '\n') do;
  170.         OutputFStm.WriteStr(RecLine);
  171.         Inc(Dripd, CrByte);
  172.         OutputFStm.WriteStr(#$0D#$0A);
  173.       end;
  174.       StringStm.Position := 0;
  175.       aEng    := False;
  176.       aHan    := False;
  177.       Crlenth := 0;
  178.       Crbyte  := 0;
  179.       CrAddon := 0;
  180.       Mixed   := False;
  181.       Flush   := False;
  182.     end;
  183.     Position0 := Spos * 100 div Ssize;
  184.     if Position1 <> Position0 then
  185.     begin
  186.       Position1 := Position0;
  187.       RarProgressBar1.Position1 := Position1;
  188.     end;
  189.     Position0 := DRipd * 100 div Ssize;
  190.     if Position2 <> Position0 then
  191.     begin
  192.       Position2 := Position0;
  193.       RarProgressBar1.Position2 := Position0;
  194.     end;
  195.   end;//while byte
  196.   StringStm.Free;
  197.   BufStm.Free;
  198.   OutputFStm.Free;
  199.   AddLog('Ripping done in ' + Int2Str(GetTickCount() - StartTick) + 'ms');
  200.   Result := 0;
  201. end;
复制代码
发表于 2008-5-26 07:27:12 | 显示全部楼层
咋看着象pascal
发表于 2008-5-26 08:10:52 | 显示全部楼层
何止要改, 不懂Pascal都看不懂..
发表于 2008-5-26 08:55:12 | 显示全部楼层
lacsap
您需要登录后才可以回帖 登录 | 加入易码

本版积分规则

Archiver|手机版|小黑屋|EMAX Studio

GMT+8, 2024-11-1 06:59 , Processed in 0.009655 second(s), 15 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表