Delphi - SysUtils.Trim 不删除最后一个 space(?) 字符
Delphi - SysUtils.Trim not deleting last space(?) char
Delphi里奥。我用 Delphi 构建了一个 Excel 插件(也使用 AddIn Express)。我遍历一列以读取单元格值。读取单元格值后,我执行 TRIM 函数。 TRIM 并没有删除最后一个 space。代码片段...
acctName := Trim(UpperCase(Acctname));
代码前AcctName为'ABC Holdings '。在 TRIM 函数之后是一样的。 Excel 似乎在那里添加了某种类型的其他字符。 (新行??回车return??)摆脱这个的最好方法是什么?有没有办法让调试器显示这个变量的十六进制值。我已经尝试了 INSPECT 和 EVALUATE windows。他们都只显示文字。请注意,我必须小心删除非文本字符,一些公司名称有破折号、逗号、撇号等。
**附加信息 - 根据 Andreas 的建议,我添加了以下内容...
ShowMessage(IntToHex(Ord(Acctname[Acctname.Length])));
返回“00A0”。所以我想我可以做一个简单的 StringReplace...所以我在 Andreas 代码之前添加这个...
acctName := StringReplace(acctName, #13, '', [rfReplaceAll]);
acctName := StringReplace(acctName, #10, '', [rfReplaceAll]);
然而,似乎什么都没有改变。 ShowMessage 仍然显示“00A0”作为最后一个字符。为什么 StringReplace 不删除它?
如果您想知道字符串最后一个字符的真实身份,可以显示其 Unicode 代码点:
ShowMessage(IntToHex(Ord(Acctname[Acctname.Length]))).
或者,您可以使用实用程序调查剪贴板上的 Unicode 字符,例如 my own。
是的,有问题的字符是U+00A0: NO-BREAK SPACE
。
这与通常的 space 类似,但它告诉渲染应用程序不要在此 space 处放置换行符。例如,至少在瑞典语中,您需要 non-breaking spaces in 5 000 kWh
.
默认Trim
and TStringHelper.Trim
不去除这种白色space。 (他们还留下 U+2007: FIGURE SPACE
和其他几种白色 space。)
字符串帮助器方法有一个重载,可让您将字符指定为 trim。您可以使用它来包含 U+00A0
:
S.Trim([#, #$A0, #, #$D, #$A]) // space, nbsp, tab, CR, LF
// (many whitespace characters missing!)
但也许更好的解决方案是依靠 Unicode 特性并执行
function RealTrimRight(const S: string): string;
var
i: Integer;
begin
i := S.Length;
while (i > 0) and S[i].IsWhiteSpace do
Dec(i);
Result := Copy(S, 1, i);
end;
当然可以实现类似RealTrimLeft
和RealTrim
的功能
当然还有很多方法可以在调试器中查看实际的字符串字节。除了在Evaluate/Modifywindow(Ctrl+F7中写Ord(S[S.Length])
之类的东西,我的个人最喜欢的方法是使用Memorywindow(Ctrl+Alt+E)。当它有焦点时,您可以按 Ctrl+G 并键入 S[1]
以查看实际字节数:
在这里您可以看到字符串 test string
。由于自 Delphi 2009 年以来字符串是 Unicode (UTF-16),因此每个字符占用两个字节。对于简单的 ASCII 字符,这意味着每隔一个字节为空。我们字符串的 ASCII 值是 74 65 73 74 20 73 74 72 69 6E 67
。您还可以看到,在上面的行 (02A0855C
) 中,我们的字符串对象具有引用计数 1
和长度 B
(=11).
作为演示,显示 unicode 字符串:
program q63847533;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
type
array100 = array[0..99] of Byte;
parray100 = ^array100;
var
searchResult : TSearchRec;
Name : string;
display : parray100 absolute Name;
dummy : string;
begin
if findfirst('z*.mp3', faAnyFile, searchResult) = 0 then
begin
repeat
writeln('File name = '+searchResult.Name);
name := searchResult.Name;
writeln('File size = '+IntToStr(searchResult.Size));
until FindNext(searchResult) <> 0;
// Must free up resources used by these successful finds
FindClose(searchResult);
end;
readln(dummy);
end.
我的目录包含两个 z*.mp3
文件,一个具有 ANSI 名称,另一个具有 Unicode 名称。
WATCHing display^
as Hex 或 Memorydump 将显示您似乎需要的内容(您问题的 Is there a way I can ask the debugger to show me the HEX value for this variable.
)
Delphi里奥。我用 Delphi 构建了一个 Excel 插件(也使用 AddIn Express)。我遍历一列以读取单元格值。读取单元格值后,我执行 TRIM 函数。 TRIM 并没有删除最后一个 space。代码片段...
acctName := Trim(UpperCase(Acctname));
代码前AcctName为'ABC Holdings '。在 TRIM 函数之后是一样的。 Excel 似乎在那里添加了某种类型的其他字符。 (新行??回车return??)摆脱这个的最好方法是什么?有没有办法让调试器显示这个变量的十六进制值。我已经尝试了 INSPECT 和 EVALUATE windows。他们都只显示文字。请注意,我必须小心删除非文本字符,一些公司名称有破折号、逗号、撇号等。
**附加信息 - 根据 Andreas 的建议,我添加了以下内容...
ShowMessage(IntToHex(Ord(Acctname[Acctname.Length])));
返回“00A0”。所以我想我可以做一个简单的 StringReplace...所以我在 Andreas 代码之前添加这个...
acctName := StringReplace(acctName, #13, '', [rfReplaceAll]);
acctName := StringReplace(acctName, #10, '', [rfReplaceAll]);
然而,似乎什么都没有改变。 ShowMessage 仍然显示“00A0”作为最后一个字符。为什么 StringReplace 不删除它?
如果您想知道字符串最后一个字符的真实身份,可以显示其 Unicode 代码点:
ShowMessage(IntToHex(Ord(Acctname[Acctname.Length]))).
或者,您可以使用实用程序调查剪贴板上的 Unicode 字符,例如 my own。
是的,有问题的字符是U+00A0: NO-BREAK SPACE
。
这与通常的 space 类似,但它告诉渲染应用程序不要在此 space 处放置换行符。例如,至少在瑞典语中,您需要 non-breaking spaces in 5 000 kWh
.
默认Trim
and TStringHelper.Trim
不去除这种白色space。 (他们还留下 U+2007: FIGURE SPACE
和其他几种白色 space。)
字符串帮助器方法有一个重载,可让您将字符指定为 trim。您可以使用它来包含 U+00A0
:
S.Trim([#, #$A0, #, #$D, #$A]) // space, nbsp, tab, CR, LF
// (many whitespace characters missing!)
但也许更好的解决方案是依靠 Unicode 特性并执行
function RealTrimRight(const S: string): string;
var
i: Integer;
begin
i := S.Length;
while (i > 0) and S[i].IsWhiteSpace do
Dec(i);
Result := Copy(S, 1, i);
end;
当然可以实现类似RealTrimLeft
和RealTrim
的功能
当然还有很多方法可以在调试器中查看实际的字符串字节。除了在Evaluate/Modifywindow(Ctrl+F7中写Ord(S[S.Length])
之类的东西,我的个人最喜欢的方法是使用Memorywindow(Ctrl+Alt+E)。当它有焦点时,您可以按 Ctrl+G 并键入 S[1]
以查看实际字节数:
在这里您可以看到字符串 test string
。由于自 Delphi 2009 年以来字符串是 Unicode (UTF-16),因此每个字符占用两个字节。对于简单的 ASCII 字符,这意味着每隔一个字节为空。我们字符串的 ASCII 值是 74 65 73 74 20 73 74 72 69 6E 67
。您还可以看到,在上面的行 (02A0855C
) 中,我们的字符串对象具有引用计数 1
和长度 B
(=11).
作为演示,显示 unicode 字符串:
program q63847533;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
type
array100 = array[0..99] of Byte;
parray100 = ^array100;
var
searchResult : TSearchRec;
Name : string;
display : parray100 absolute Name;
dummy : string;
begin
if findfirst('z*.mp3', faAnyFile, searchResult) = 0 then
begin
repeat
writeln('File name = '+searchResult.Name);
name := searchResult.Name;
writeln('File size = '+IntToStr(searchResult.Size));
until FindNext(searchResult) <> 0;
// Must free up resources used by these successful finds
FindClose(searchResult);
end;
readln(dummy);
end.
我的目录包含两个 z*.mp3
文件,一个具有 ANSI 名称,另一个具有 Unicode 名称。
WATCHing display^
as Hex 或 Memorydump 将显示您似乎需要的内容(您问题的 Is there a way I can ask the debugger to show me the HEX value for this variable.
)