我正在从Apache Commons库中移植一些类,我发现以下行为很奇怪。我有一个正则表达式定义为
const
IPV4_REGEX = '^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$';
我按如下方式使用它:
ipv4Validator: TRegEx;
ipv4Validator := TRegEx.Create(IPV4_REGEX);
当我使用它来匹配IP地址时,以下代码返回false - 调试器显示Match.Groups.Count
为5,这是我没想到的。
var
Match: TMatch;
begin
Match := ipv4Validator.Match(inet4Address);
if Match.Groups.Count <> 4 then
Exit(false);
这是TMatch.Groups.Count的正确行为吗?
以防万一,这是我班级的完整代码。请注意,我已经评论了违规行,因为它使我的测试失败了。
unit InetAddressValidator;
interface
uses RegularExpressions;
const
IPV4_REGEX = '^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$';
type
TInetAddressValidator = class
private
ipv4Validator: TRegEx;
public
constructor Create; overload;
function isValid(const inetAddress: String): Boolean;
function isValidInet4Address(const inet4Address: String): Boolean;
end;
implementation
uses SysUtils;
constructor TInetAddressValidator.Create;
begin
inherited;
ipv4Validator := TRegEx.Create(IPV4_REGEX);
end;
function TInetAddressValidator.isValid(const inetAddress: String): Boolean;
begin
Result := isValidInet4Address(inetAddress);
end;
function TInetAddressValidator.isValidInet4Address(const inet4Address
: String): Boolean;
var
Match: TMatch;
IpSegment: Integer;
i: Integer;
begin
Match := ipv4Validator.Match(inet4Address);
// if Match.Groups.Count <> 4 then
// Exit(false);
IpSegment := 0;
for i := 1 to Match.Groups.Count - 1 do
begin
try
IpSegment := StrToInt(Match.Groups[i].Value);
except
Exit(false);
end;
if IpSegment > 255 then
Exit(false);
end;
Result := true;
end;
end.
答案 0 :(得分:4)
Match.Groups [0]包含整个表达式,所以这是正确的。
TGroupcollection构造函数:
constructor TGroupCollection.Create(ARegEx: TPerlRegEx;
const AValue: UTF8String; AIndex, ALength: Integer; ASuccess: Boolean);
var
I: Integer;
begin
FRegEx := ARegEx;
/// populate collection;
if ASuccess then
begin
SetLength(FList, FRegEx.GroupCount + 1);
for I := 0 to Length(FList) - 1 do
FList[I] := TGroup.Create(AValue, FRegEx.GroupOffsets[I], FRegEx.GroupLengths[I], ASuccess);
end;
end;
正如您所看到的,内部Flist(TArray<TGroup>
)以组数+ 1开始.FList [0]接收具有偏移量1和整个表达式长度的组。此行为未记录。
答案 1 :(得分:1)
Delphi的TRegEx
旨在模仿.NET的Regex
类,它还将整体正则表达式匹配添加到Match.Groups.Count
。 .NET执行此操作以便GroupCollection
类可以实现ICollection
接口。
在Java Matcher.group(0)
中也返回整体正则表达式匹配。 Matcher.groupCount()
返回不包括整体匹配的组数。大多数正则表达式库都是这样做的。