{*******************************************************} { } { Methods of Sting } { } { CopyRight (C) 2018-2020 KngStr } { } { Some Code from } { QDAC of swish } { Thanks } { } {*******************************************************} unit ksString; interface /// /// 创建空白文件 /// function CreateBlankFile(S: string): Boolean; /// /// 自动为已存在文件名加数字 /// function AutoChangeFileName(AFile: string): string; /// /// 自动替换文件名中的非法字符为 /// procedure ChangeInvalidFileNameChars(var FileName: string; AChar: Char = '_'); /// /// 格式化秒为时间,冒号分割 /// function FormatSeconds(const AValue: Int64): string; overload; /// /// 格式化秒为时间,冒号分割 /// function FormatSeconds(const AValue: Integer): string; overload; /// /// 格式化秒为时间,冒号分割 /// function FormatSeconds(const AValue: Double): string; overload; /// /// 格式化文件大小,拷贝自qdac,增加更多单位 /// function FormatSize(ASize: Int64): string; /// /// 文件大小字符串转数字 /// 1[b] "1 k[b]" " 1 m[b] " 1g[b] 1t[b] /// function SizeStrToInt(ASize: string; ADefault: Int64 = 0): Int64; /// /// 文件大小单位转数字 /// function SizeUnitToInt(AUnit: string): Int64; overload; /// /// 文件大小单位转数字 /// function SizeUnitToInt(AUnit: Char): Int64; overload; /// /// 是否中国手机号 /// 13900000000 /// +8613900000000 /// +86 139 0000 0000 /// +86-139-0000-0000 /// /// 仅允许数字和开头的+ function IsChineseMobileNumber(S: string; AOnlyNum: Boolean = False): Boolean; implementation uses Classes, SysUtils, IOUtils; function CreateBlankFile(S: string): Boolean; var FStrm: TFileStream; begin Result := False; try FStrm := TFileStream.Create(S, fmCreate); if FStrm = nil then Exit; Result := True; FreeAndNil(FStrm); except FStrm := nil; end; end; function AutoChangeFileName(AFile: string): string; var I: Integer; sPath, sExt: string; begin Result := AFile; I := 0; sPath := ChangeFileExt(Result, ''); sExt := ExtractFileExt(Result); while FileExists(Result) do begin Inc(I); Result := Format('%s(%d)%s', [sPath, I, sExt]); end; end; procedure ChangeInvalidFileNameChars(var FileName: string; AChar: Char); var PFileName: PChar; FileNameLen: Integer; Ch: Char; I: Integer; begin I := 0; PFileName := PChar(FileName); FileNameLen := Length(FileName); while I < FileNameLen do begin Ch := PFileName[I]; if not TPath.IsValidFileNameChar(Ch) then PFileName[I] := AChar else Inc(I); end; end; function FormatSeconds(const AValue: Double): string; overload; var h, m, s, ms: Integer; begin ms := Trunc(Frac(AValue) * 1000); s := Trunc(AValue); m := s div 60; h := m div 60; if h > 0 then Result := Format('%.2d:%.2d:%.2d.%.3d', [h, m mod 60, s mod 60, ms]) else Result := Format('%.2d:%.2d.%.3d', [m, s mod 60, ms]); end; function FormatSeconds(const AValue: Int64): string; var h, m, s: Integer; begin s := AValue; m := s div 60; h := m div 60; if h > 0 then Result := Format('%.2d:%.2d:%.2d', [h, m mod 60, s mod 60]) else Result := Format('%.2d:%.2d', [m, s mod 60]); end; function FormatSeconds(const AValue: Integer): string; overload; begin FormatSeconds(Int64(AValue)); end; function FormatSize(ASize: Int64): string; var AIdx, R1, s1: Int64; AIsNeg: Boolean; const Units: array [0 .. 6] of string = ('EB', 'PB', 'TB', 'GB', 'MB', 'KB', 'B'); begin AIsNeg := (ASize < 0); AIdx := 6; R1 := 0; if AIsNeg then ASize := -ASize; Result := ''; while (AIdx >= 0) do begin s1 := ASize mod 1024; ASize := ASize shr 10; if (ASize = 0) or (AIdx = 0) then begin R1 := R1 * 100 div 1024; if R1 > 0 then begin if R1 >= 10 then Result := IntToStr(s1) + '.' + IntToStr(R1) + Units[AIdx] else Result := IntToStr(s1) + '.' + '0' + IntToStr(R1) + Units[AIdx]; end else Result := IntToStr(s1) + Units[AIdx]; Break; end; R1 := s1; Dec(AIdx); end; if AIsNeg then Result := '-' + Result; end; function IsChineseMobileNumber(S: string; AOnlyNum: Boolean): boolean; var p: PChar; i: Integer; begin Result := False; // 最短肯定是11位 if (Length(S) < 11) then Exit; i := 0; p := PChar(S); while p^ <> #0 do begin if p^ = '+' then begin if i > 0 then // +号必须在第一位 Exit; if (p[1] = '8') and (p[2] = '6') then // +86,而且是连续的 Inc(p, 3) else Exit; end else if ((p^ >= '0') and (p^ <= '9')) then begin if (i = 0) and (p^ <> '1') then // 中国手机号都是1开头 Exit; Inc(p); Inc(i); end else if (not AOnlyNum) and ((p^ = '-') or (p^ = ' ')) then Inc(p) else Exit; end; Result := i = 11; //中国手机号 11位 end; function SizeUnitToInt(AUnit: Char): Int64; const Units: array [0 .. 6] of Char = ('b', 'k', 'm', 'g', 't', 'p', 'e'); var I: Integer; begin Result := 1; for I := Low(Units) to High(Units) do begin if (I > 0) then Result := Result * 1024; if AUnit = Units[I] then Exit; end; Result := 1; end; function SizeUnitToInt(AUnit: string): Int64; var LSize: string; begin Result := 1; LSize := Trim(AUnit); case Length(LSize) of 1,2: Result := SizeUnitToInt(LSize[Low(LSize)]); end; end; function SizeStrToInt(ASize: string; ADefault: Int64): Int64; var p: PChar; c: Char; s: string; begin Result := ADefault; if Length(ASize) = 0 then Exit; s := ''; c := #0; p := PChar(ASize); while p^ <> #0 do case p^ of 'b', 'k', 'm', 'g', 't', 'p', 'e': begin if c <> #0 then Exit; c := p^; Inc(p); if p^ = 'b' then Inc(p); end; '0' .. '9': begin if c <> #0 then Exit; s := s + p^; Inc(p); end; ',': begin if c <> #0 then Exit; Inc(p); end; ' ': Inc(p); else Exit; end; Result := StrToUInt64Def(s, Result) * SizeUnitToInt(c); end; end.