Trang Chủ | Diễn Đàn | Thành Viên (Đăng Ký) | Tìm Kiếm | Tutorial Room
Delphi - Chuyển tiếng Việt có dấu sang không dấu?
Hỏi đáp, trao đổi về lập trình Delphi.
Chú ý: Pascal/Delphi FAQs
First page Previous page  (Page 1 )   1   Next page Last page
Chuyển tiếng Việt có dấu sang không dấu?
Member
Member since
19:48 04-06-2005
Posts: 328
Fantasy Points: 2,594
question Posted at 06:21 28-09-2009 Move Move Topic   Pin/Unpin Pin Topic   Lock Lock Topic
Để chuyển tiếng Việt có dấu thành không dấu, ngoài cách tìm kiếm và thay thế, có cách nào tổng quát hơn không?
___________________________
sorry for my bad En...
This post has been edited 1 time(s). Last edited by freeman on 06:21 28-09-2009.
Reply Reply   Quote Quote   Edit Edit   Delete Delete   Report Report
This post has been viewed 3,082 time(s). 2 direct repli(es) and 1 indirect repli(es).
Title Poster
question Chuyển tiếng Việt có dấu sang không dấu?
 
answer Re: Chuyển tiếng Việt có dấu sang không dấu?
quan
answer Re: Chuyển tiếng Việt có dấu sang không dấu?
NBThanh
Re: Chuyển tiếng Việt có dấu sang không dấu?
Member
Member since
19:30 12-02-2002
Posts: 385
Fantasy Points: 6,459
Rank
answer Posted at 09:09 28-09-2009
Reply to Chuyển tiếng Việt có dấu sang không dấu? (freeman)
Phân rã hoàn toàn các ký tự rồi delete các dấu thanh. Thí dụ sau trong C#; không biết Delphi có hàm tương tự.

/**
* Strips accents off words
*/
public static string StripDiacritics(string accented)
{
    Regex regex = new Regex("\pp{IsCombiningDiacriticalMarks}+");

    string strFormD = accented.Normalize(NormalizationForm.FormD);
    return regex.Replace(strFormD, String.Empty).Replace('\u0111', 'd').Replace('\u0110', 'D');
}
Reply Reply   Quote Quote   Edit Edit   Delete Delete   Report Report
This post has been viewed 3,074 time(s). 0 direct repli(es) and 0 indirect repli(es).
Re: Chuyển tiếng Việt có dấu sang không dấu?
Forum Moderator
Member since
20:03 17-08-2001
Posts: 18,047
Fantasy Points: 154,606
Rank
answer Posted at 11:08 28-09-2009
Reply to Chuyển tiếng Việt có dấu sang không dấu? (freeman)
freeman:
Để chuyển tiếng Việt có dấu thành không dấu, ngoài cách tìm kiếm và thay thế, có cách nào tổng quát hơn không?

Không thấy cái Lib đi kèm nào với Delphi hỗ trợ Unicode Normalization nên cách "tổng quát hơn" e là không có.
Còn nếu bạn sử dụng Delphi .NET thì bạn có thể sử dụng các mà bạn Quân trình bày.
Reply Reply   Quote Quote   Edit Edit   Delete Delete   Report Report
This post has been viewed 3,069 time(s). 1 direct repli(es) and 0 indirect repli(es).
Title Poster
answer Re: Chuyển tiếng Việt có dấu sang không dấu?
 
answer Re: Chuyển tiếng Việt có dấu sang không dấu?
freeman
Re: Chuyển tiếng Việt có dấu sang không dấu?
Member
Member since
19:48 04-06-2005
Posts: 328
Fantasy Points: 2,594
answer Posted at 20:09 28-09-2009
Reply to Re: Chuyển tiếng Việt có dấu sang không dấu? (NBThanh)
Cám ơn các bạn. Trong C# có sẵn hàm "normalize" chuỗi unicode nên dễ hơn Delphi.

Đây là hàm "thủ công" (tìm và thay) tôi viết trên Delphi, chia sẻ cho những bạn có nhu cầu sử dụng:

function ManipulateNormalizeUnicode2Byte(AString: WideString): WideString;
const
{  LowerASet: set of WideChar = ['á', 'à', 'ả', 'ã', 'ạ',
    'â', 'ấ', 'ầ', 'ẩ', 'ẫ', 'ậ', 'ă', 'ắ', 'ằ', 'ẳ', 'ẵ', 'ặ'];
  UpperASet: set of WideChar = ['Á', 'À', 'Ả', 'Ã', 'Ạ',
    'Â', 'Ấ', 'Ầ', 'Ẩ', 'Ẫ', 'Ậ', 'Ă', 'Ắ', 'Ằ', 'Ẳ', 'Ẵ', 'Ặ'];
  LowerESet: set of WideChar = ['é', 'è', 'ẻ', 'ẽ', 'ẹ',
    'ê', 'ế', 'ề', 'ể', 'ễ', 'ệ'];
  UpperESet: set of WideChar = ['É', 'È', 'Ẻ', 'Ẽ', 'Ẹ',
    'Ê', 'Ế', 'Ề', 'Ể', 'Ễ', 'Ệ'];
  LowerISet: set of WideChar = ['í', 'ì', 'ỉ', 'ĩ', 'ị'];
  UpperISet: set of WideChar = ['Í', 'Ì', 'Ỉ', 'Ĩ', 'Ị'];
  LowerOSet: set of WideChar = ['ó', 'ò', 'ỏ', 'õ', 'ọ',
    'ô', 'ố', 'ồ', 'ổ', 'ỗ', 'ộ', 'ơ', 'ớ', 'ờ', 'ở', 'ỡ', 'ợ'];
  UpperOSet: set of WideChar = ['Ó', 'Ò', 'Ỏ', 'Õ', 'Ọ',
    'Ô', 'Ố', 'Ồ', 'Ổ', 'Ỗ', 'Ộ', 'Ơ', 'Ớ', 'Ờ', 'Ở', 'Ỡ', 'Ợ'];
  LowerUSet: set of WideChar = ['ú', 'ù', 'ủ', 'ũ', 'ụ',
    'ư', 'ứ', 'ừ', 'ử', 'ữ', 'ự'];
  UpperUSet: set of WideChar = ['Ú', 'Ù', 'Ủ', 'Ũ', 'Ụ',
    'Ư', 'Ứ', 'Ừ', 'Ử', 'Ữ', 'Ự'];
  LowerYSet: set of WideChar = ['ý', 'ỳ', 'ỷ', 'ỹ', 'ỵ'];
  UpperYSet: set of WideChar = ['Ý', 'Ỳ', 'Ỷ', 'Ỹ', 'Ỵ'];
}
  LowerASet: array[0..16] of Word = ($00E1, $00E0, $1EA3, $00E3, $1EA1,
    $00E2, $1EA5, $1EA7, $1EA9, $1EAB, $1EAD,
    $0103, $1EAF, $1EB1, $1EB3, $1EB5, $1EB7);
  UpperASet: array[0..16] of Word = ($00C1, $00C0, $1EA2, $00C3, $1EA0,
    $00C2, $1EA4, $1EA6, $1EA8, $1EAA, $1EAC,
    $0102, $1EAE, $1EB0, $1EB2, $1EB4, $1EB6);
  LowerESet: array[0..10] of Word = ($00E9, $00E8, $1EBB, $1EBD, $1EB9,
    $00EA, $1EBF, $1EC1, $1EC3, $1EC5, $1EC7);
  UpperESet: array[0..10] of Word = ($00C9, $00C8, $1EBA, $1EBC, $1EB8,
    $00CA, $1EBE, $1EC0, $1EC2, $1EC4, $1EC6);
  LowerISet: array[0..4] of Word = ($00ED, $00EC, $1EC9, $0129, $1ECB);
  UpperISet: array[0..4] of Word = ($00CD, $00CC, $1EC8, $0128, $1ECA);
  LowerOSet: array[0..16] of Word = ($00F3, $00F2, $1ECF, $00F5, $1ECD,
    $00F4, $1ED1, $1ED3, $1ED5, $1ED7, $1ED9,
    $01A1, $1EDB, $1EDD, $1EDF, $1EE1, $1EE3);
  UpperOSet: array[0..16] of Word = ($00D3, $00D2, $1ECE, $00D5, $1ECC,
    $00D4, $1ED0, $1ED2, $1ED4, $1ED6, $1ED8,
    $01A0, $1EDA, $1EDC, $1EDE, $1EE0, $1EE2);
  LowerUSet: array[0..10] of Word = ($00FA, $00F9, $1EE7, $0169, $1EE5,
    $01B0, $1EE9, $1EEB, $1EED, $1EEF, $1EF1);
  UpperUSet: array[0..10] of Word = ($00DA, $00D9, $1EE6, $0168, $1EE4,
    $01AF, $1EE8, $1EEA, $1EEC, $1EEE, $1EF0);
  LowerYSet: array[0..4] of Word = ($00FD, $1EF3, $1EF7, $1EF9, $1EF5);
  UpperYSet: array[0..4] of Word = ($00DD, $1EF2, $1EF6, $1EF8, $1EF4);
  LowerDSet: array[0..0] of Word = ($0111);
  UpperDSet: array[0..0] of Word = ($0110);
//
  function Check(CharCode: Word; Values: array of Word): Boolean;
  // hàm trả về True nếu CharCode có trong mảng ký tự có dấu của tiếng Việt
  var
    i: Byte;
  begin
    for i := 0 to High(Values) do
    begin
      Result := Values[i] = CharCode;
      if Result then Break;
    end;
  end;
//
var
  i: Integer;
  CharCode: Word;
begin
  Result := AString;
  for i := 1 to Length(Result) do
  begin
    CharCode := Word(Result[i]);
    // dùng if..else liên tục để thoát vòng lặp và nhảy đến ký tự kế tiếp
    // ngay khi xử lý xong 1 ký tự, tránh trường hợp so sánh nhiều lần
    // ở nhiều mảng ký tự khác nhau
    if Check(CharCode, LowerASet) then
      Result[i] := 'a'
    else if Check(CharCode, UpperASet) then
      Result[i] := 'A'
    else if Check(CharCode, LowerESet) then
      Result[i] := 'e'
    else if Check(CharCode, UpperESet) then
      Result[i] := 'E'
    else if Check(CharCode, LowerISet) then
      Result[i] := 'i'
    else if Check(CharCode, UpperISet) then
      Result[i] := 'I'
    else if Check(CharCode, LowerOSet) then
      Result[i] := 'o'
    else if Check(CharCode, UpperOSet) then
      Result[i] := 'O'
    else if Check(CharCode, LowerUSet) then
      Result[i] := 'u'
    else if Check(CharCode, UpperUSet) then
      Result[i] := 'U'
    else if Check(CharCode, LowerYSet) then
      Result[i] := 'y'
    else if Check(CharCode, UpperYSet) then
      Result[i] := 'Y'
    else if Check(CharCode, LowerDSet) then
      Result[i] := 'd'
    else if Check(CharCode, UpperDSet) then
      Result[i] := 'D';
  end;
end;


Tôi làm chương trình trên nền WinForm, kiểm thử với 100.000 truy vấn tìm kiếm, mỗi truy vấn trung bình là một chuỗi unicode 10 ~ 13 ký tự, kết quả khi gọi hàm trên thì thời gian tiêu tốn hơn khoảng 110% so với không gọi hàm. Như vậy có lẽ cũng tạm ổn :)

Nếu bạn nào còn cách khác tối ưu hơn vui lòng trình bày để mọi người cùng sử dụng, cám ơn bạn.
___________________________
sorry for my bad En...
This post has been edited 2 time(s). Last edited by freeman on 19:12 17-12-2009.
Reply Reply   Quote Quote   Edit Edit   Delete Delete   Report Report
This post has been viewed 3,049 time(s). 0 direct repli(es) and 0 indirect repli(es).
First page Previous page  (Page 1 )   1   Next page Last page

Permissions: Create Topic: No  |  Reply Topic: No  |  Attach File: No  |  Make Poll: No

Vietnamese Keyboard: AUTO TELEX VNI VIQR VIQR* OFF

Go top || Print page ||

All logos, trademarks and graphics artwork in this site are property of their respective owners.
Opinions expressed in articles within this site are those of their owners and may not reflect the opinion of TXBB.

TXBB: Home - Disclaimer - Help - Contact
Copyright (C) 2000-2006 TXBB. All rights reserved.

TreXanh Bulletin Board v2.0 (Build: #332 Nov 21, 2006)

DEBUG INFORMATION
Execution 0.137s - SQL used 5s - Concurrent process(es) 0