Delphi 带有 UTF8 字符串的 Firebird UDF
Delphi Firebird UDF with UTF8 strings
我们正在尝试在 Delphi(西雅图 10 号)为我们的 Firebird 2.5 数据库编写一个 UDF,它应该从输入字符串中删除一些字符。
我们数据库中的所有字符串字段都使用字符集 UTF8 和排序规则 UNICODE_CI_AI.
该函数应该删除一些字符,例如 space, 。 ; : / \ 和其他字符串。
我们的函数适用于包含 ascii 值 <= 127 的字符的字符串。只要存在 ascii 值大于 127 的字符,UDF 就会失败。
我们尝试使用 PChar 而不是 PAnsiChar 参数但没有成功。现在我们检查字符的 ascii 值是否大于 127,如果是,我们也从字符串中删除该字符。
不过,我们想要的是一个 UDF returns 没有标点符号的原始字符串。
到目前为止,这是我们的代码:
unit UDFs;
interface
uses ib_util;
function UDF_RemovePunctuations(InputString: PAnsiChar): PAnsiChar; cdecl;
implementation
uses SysUtils, AnsiStrings, Classes;
//FireBird declaration:
//DECLARE EXTERNAL FUNCTION UDF_REMOVEPUNCTUATIONS
// CSTRING(500)
//RETURNS CSTRING(500) FREE_IT
//ENTRY_POINT 'UDF_RemovePunctuations' MODULE_NAME 'FB_UDF.dll';
function UDF_RemovePunctuations(InputString: PAnsiChar): PAnsiChar;
const
PunctuationChars = [' ', ',', '.', ';', '/', '\', '''', '"','(', ')'];
var
I: Integer;
S, NewS: String;
begin
S := UTF8ToUnicodeString(InputString);
For I := 1 to Length(S) do
begin
If Not CharInSet(S[I], PunctuationChars)
then begin
If S[I] <= #127
then NewS := NewS + S[I];
end;
end;
Result := ib_util_malloc(Length(NewS) + 1);
NewS := NewS + #0;
AnsiStrings.StrPCopy(Result, NewS);
end;
end.
当我们删除对 ascii 值 <= #127 的检查时,我们可以看到 NewS 包含了它应该包含的所有字符(当然没有标点符号字符)但是在执行我们认为的 StrPCopy 时出现了问题。
如有任何帮助,我们将不胜感激!
多亏了 LU RD 我才开始工作。
答案是将我的字符串变量声明为 Utf8String 而不是 String 并且不将输入字符串转换为 Unicode。
我已经这样调整了我的代码:
//FireBird declaration:
//DECLARE EXTERNAL FUNCTION UDF_REMOVEPUNCTUATIONS
// CSTRING(500)
//RETURNS CSTRING(500) FREE_IT
//ENTRY_POINT 'UDF_RemovePunctuations' MODULE_NAME 'CarfacPlus_UDF.dll';
function UDF_RemovePunctuations(InputString: PAnsiChar): PAnsiChar;
const
PunctuationChars = [' ', ',', '.', ';', '/', '\', '''', '"','(', ')', '-',
'+', ':', '<', '>', '=', '[', ']', '{', '}'];
var
I: Integer;
S: Utf8String;
begin
S := InputString;
For I := Length(S) downto 1 do
If CharInSet(S[I], PunctuationChars)
then Delete(S, I, 1);
Result := ib_util_malloc(Length(S) + 1);
AnsiStrings.StrPCopy(Result, AnsiString(S));
end;
我们正在尝试在 Delphi(西雅图 10 号)为我们的 Firebird 2.5 数据库编写一个 UDF,它应该从输入字符串中删除一些字符。 我们数据库中的所有字符串字段都使用字符集 UTF8 和排序规则 UNICODE_CI_AI.
该函数应该删除一些字符,例如 space, 。 ; : / \ 和其他字符串。 我们的函数适用于包含 ascii 值 <= 127 的字符的字符串。只要存在 ascii 值大于 127 的字符,UDF 就会失败。 我们尝试使用 PChar 而不是 PAnsiChar 参数但没有成功。现在我们检查字符的 ascii 值是否大于 127,如果是,我们也从字符串中删除该字符。
不过,我们想要的是一个 UDF returns 没有标点符号的原始字符串。
到目前为止,这是我们的代码:
unit UDFs;
interface
uses ib_util;
function UDF_RemovePunctuations(InputString: PAnsiChar): PAnsiChar; cdecl;
implementation
uses SysUtils, AnsiStrings, Classes;
//FireBird declaration:
//DECLARE EXTERNAL FUNCTION UDF_REMOVEPUNCTUATIONS
// CSTRING(500)
//RETURNS CSTRING(500) FREE_IT
//ENTRY_POINT 'UDF_RemovePunctuations' MODULE_NAME 'FB_UDF.dll';
function UDF_RemovePunctuations(InputString: PAnsiChar): PAnsiChar;
const
PunctuationChars = [' ', ',', '.', ';', '/', '\', '''', '"','(', ')'];
var
I: Integer;
S, NewS: String;
begin
S := UTF8ToUnicodeString(InputString);
For I := 1 to Length(S) do
begin
If Not CharInSet(S[I], PunctuationChars)
then begin
If S[I] <= #127
then NewS := NewS + S[I];
end;
end;
Result := ib_util_malloc(Length(NewS) + 1);
NewS := NewS + #0;
AnsiStrings.StrPCopy(Result, NewS);
end;
end.
当我们删除对 ascii 值 <= #127 的检查时,我们可以看到 NewS 包含了它应该包含的所有字符(当然没有标点符号字符)但是在执行我们认为的 StrPCopy 时出现了问题。
如有任何帮助,我们将不胜感激!
多亏了 LU RD 我才开始工作。
答案是将我的字符串变量声明为 Utf8String 而不是 String 并且不将输入字符串转换为 Unicode。
我已经这样调整了我的代码:
//FireBird declaration:
//DECLARE EXTERNAL FUNCTION UDF_REMOVEPUNCTUATIONS
// CSTRING(500)
//RETURNS CSTRING(500) FREE_IT
//ENTRY_POINT 'UDF_RemovePunctuations' MODULE_NAME 'CarfacPlus_UDF.dll';
function UDF_RemovePunctuations(InputString: PAnsiChar): PAnsiChar;
const
PunctuationChars = [' ', ',', '.', ';', '/', '\', '''', '"','(', ')', '-',
'+', ':', '<', '>', '=', '[', ']', '{', '}'];
var
I: Integer;
S: Utf8String;
begin
S := InputString;
For I := Length(S) downto 1 do
If CharInSet(S[I], PunctuationChars)
then Delete(S, I, 1);
Result := ib_util_malloc(Length(S) + 1);
AnsiStrings.StrPCopy(Result, AnsiString(S));
end;