我有三个函数可以成功地从给定字符串中删除所有非数字字符:
第一个函数循环遍历输入字符串的字符,如果当前字符是数字,则将其添加到作为函数结果返回的新字符串中。
function RemoveNonNumericChars(const s: string): string;
begin
Result := '';
for var i := 1 to Length(s) do
begin
if s[i] in ['0'..'9'] then
Result := Result + s[i];
end;
end;
第二个函数从右到左循环输入字符串中的字符,如果当前字符不是数字,则使用Delete
函数将其从字符串中删除
function RemoveNonNumericChars(const s: string): string;
begin
Result := s;
for var i := Length(Result) downto 1 do
begin
if not(Result[i] in ['0'..'9']) then
Delete(Result, i, 1);
end;
end;
第三个函数使用正则表达式将所有非数字字符替换为空,从而将它们删除。TRegEx
来自System.RegularExpressions
单元。
function RemoveNonNumericChars(const s: string): string;
begin
var RegEx := TRegEx.Create('[^0-9]');
Result := RegEx.Replace(s, '');
end;
这三个函数都能满足我的需要,但我想知道 Delphi 中是否有内置函数来实现这个功能...或者有比我现在的方法更好的方法。在Delphi中,从字符串中删除非数字字符的最好和/或最快的方法是什么?
1条答案
按热度按时间qnzebej01#
这两种方法都很慢,因为要不断地改变字符串的长度,而且它们只能识别阿拉伯数字。
要解决性能问题,请预分配最大结果长度:
要支持非阿拉伯数字,请使用
TCharacter.IsDigit
函数:为了进一步优化,正如Stefan Glienke所建议的,可以绕过RTL的字符串处理机制,直接编写每个字符,但会损失一些代码可读性:
基准
为了好玩,我对长度小于100的随机输入字符串做了一个非常原始的基准测试,其中字符串是数字的概率约为24%:
结果:
正如您所看到的,至少在这个测试中,正则表达式是迄今为止最慢的方法,预分配带来了很大的不同,而避免
_UniqueStringU
问题似乎只带来了相对较小的改进。但是即使使用非常慢的RegEx方法,你也可以每秒调用40000个,在我13年前的电脑上。