中文大寫數字,規範的寫法有這樣一些:
二十一
二百二十一
柒仟壹佰零壹
十四萬五千
一百一十五萬零二十
十二億六千萬
如何將它parse成數字呢?偶使用了遞歸下降的方法。即,認爲它的語法是這樣的:
(billion億)(nt10000萬)(nt1000千)(nt100百)(nt10十)(nt1)
其中,billion又可以是:(nt10000萬)(nt1000千)(nt100百)(nt10十)(nt1)
nt10000又可以是:(nt1000千)(nt100百)(nt10十)(nt1)
nt1000可以是:(nt100百)(nt10十)(nt1)
以此類推。以下帖出delphi源碼:
{ 中文字符串到數字轉化
不支持的格式有: 二二一(數字連寫),一萬萬(非標準進制,應爲一億),二千萬億(超過32位範圍) }
function ParseChNumber(const Text: string): Integer;
const
ChNums: array[1..10] of string = ('一', '二', '三', '四', '五', '六', '七', '八', '九', '十');
ChNumsBig: array[1..10] of string = ('壹', '貳', '叄', '肆', '伍', '陸', '柒', '捌', '玖', '拾');
function TryGetChNumber(const S: string): Integer;
var
I: Integer;
begin
if S = '零' then
begin
Result := 0;
Exit;
end;
if S = '兩' then
begin
Result := 2;
Exit;
end;
for I := 1 to 10 do
if (ChNums[I] = S) or (ChNumsBig[I] = S) then
begin
Result := I;
Exit;
end;
Result := -1;
end;
type
TNType = (ntBillion, nt10000, nt1000, nt100, nt10, nt1);
function ParseN(var S: string; NT: TNType): Integer;
var
I: Integer;
Vals: string;
begin
Result := 0;
if S = '' then Exit;
if Copy(S, 1, 2) = '零' then S := Copy(S, 3, MaxInt);
case NT of
ntBillion:
begin
I := Pos('億', S);
if I <= 0 then Exit;
Vals := Copy(S, 1, I - 1);
S := Copy(S, I + 2, MaxInt);
Inc(Result, ParseN(Vals, nt10000));
Inc(Result, ParseN(Vals, nt1000));
Inc(Result, ParseN(Vals, nt100));
Inc(Result, ParseN(Vals, nt10));
Inc(Result, ParseN(Vals, nt1));
Result := Result * 100000000;
end;
nt10000:
begin
I := Pos('萬', S);
if I <= 0 then Exit;
Vals := Copy(S, 1, I - 1);
S := Copy(S, I + 2, MaxInt);
Inc(Result, ParseN(Vals, nt1000));
Inc(Result, ParseN(Vals, nt100));
Inc(Result, ParseN(Vals, nt10));
Inc(Result, ParseN(Vals, nt1));
Result := Result * 10000;
end;
nt1000:
begin
I := Pos('千', S);
if I <= 0 then Exit;
Vals := Copy(S, 1, I - 1);
S := Copy(S, I + 2, MaxInt);
// nt100和nt10可去掉,因爲沒有'X百X十千'的說法
Inc(Result, ParseN(Vals, nt100));
Inc(Result, ParseN(Vals, nt10));
Inc(Result, ParseN(Vals, nt1));
Result := Result * 1000;
end;
nt100:
begin
I := Pos('百', S);
if I <= 0 then Exit;
Vals := Copy(S, 1, I - 1);
S := Copy(S, I + 2, MaxInt);
// nt10可去掉
Inc(Result, ParseN(Vals, nt10));
Inc(Result, ParseN(Vals, nt1));
Result := Result * 100;
end;
nt10:
begin
I := Pos('十', S);
if I <= 0 then Exit;
Vals := Copy(S, 1, I - 1);
S := Copy(S, I + 2, MaxInt);
Inc(Result, ParseN(Vals, nt1));
if Result = 0 then Result := 1;
Result := Result * 10;
end;
nt1:
begin
Result := TryGetChNumber(Copy(S, 1, 2));
if Result < 0 then Result := 0;
S := Copy(S, 3, MaxInt);
end;
end;
end;
var
S: string;
begin
Result := 0;
S := Text;
Inc(Result, ParseN(S, ntBillion));
Inc(Result, ParseN(S, nt10000));
Inc(Result, ParseN(S, nt1000));
Inc(Result, ParseN(S, nt100));
Inc(Result, ParseN(S, nt10));
Inc(Result, ParseN(S, nt1));
end;