How can I separate the server name from the port number in a string?
If there is a mail server string like smtp.gmail.com:587, how could I parse it开发者_运维知识库 to save "smtp.gmail.com" in a string variable and "587" in another?
function SplitAtChar(const Str: string; const Chr: char;
out Part1, Part2: string): boolean;
var
ChrPos: integer;
begin
result := true;
ChrPos := Pos(Chr, Str);
if ChrPos = 0 then
Exit(false);
Part1 := Copy(Str, 1, ChrPos - 1);
Part2 := Copy(Str, ChrPos + 1, MaxInt);
end;
Sample usage:
var
p1, p2: string;
begin
if SplitAtChar('smtp.gmail.com:587', ':', p1, p2) then
begin
ShowMessage(p1);
ShowMessage(p2);
end;
If you are using Delphi XE and want a one-liner instead of bothering with regex:
uses
Types, StrUtils;
var
StrArr: TStringDynArray;
begin
StrArr := SplitString('smtp.gmail.com:587', ':');
Assert(StrArr[0] = 'smtp.gmail.com');
Assert(StrArr[1] = '587');
end.
If you're using Delphi XE, you might also use the built-in regular expression support:
uses RegularExpressions;
procedure parse(const pInput: string; var vHostname,
vPortNumber: string);
var
l_Regex: TRegEx;
l_Match: TMatch;
begin
l_Regex := TRegEx.Create('^([a-zA-Z0-9.]+)(:([0-9]+))?$');
l_Match := l_RegEx.Match(pInput);
if l_Match.Success then
begin
vHostname := l_Match.Groups[1].Value;
if l_Match.Groups.Count > 3 then
vPortNumber := l_Match.Groups[3].Value
else
vPortNumber := '25'; // default SMTP port
end
else
begin
vHostname := '';
vPortNumber := '';
end;
end;
This will match smtp.gmail.com:587, as well as smtp.gmail.com (in the latter case, vPortNumber is assigned the standard SMTP port 25).
The Indy TIdURI class can split any URI into its parts (protocol, host, port, user, password, path, etc). Indy is included in Delphi. TIdURI bas some bugs reported here and mentioned here, planned to be fixed in Indy 11.
精彩评论