I have built a match pattern in RegexBuddy which behaves exactly as I expect. But I cannot transfer this to Delphi XE, at least when using the latest built in TRegEx or TPerlRegEx.
My real world code have 6 capture group but I can illustrate the problem in an easier example. This code gives “3” in first dialog and then raises an exception (-7 index out of bounds) when executing the second dialog.
var
Regex: TRegEx;
M: TMatch;
begin
Regex := TRegEx.Create('(?P<time>\d{1,2}:\d{1,2})(?P<judge>.{1,3})');
M := Regex.Match('00:00 X1 90 55KENNY BENNY');
ShowMessage(IntToStr(M.Groups.Count));
ShowMessage(M.Groups['time'].Value);
end;
But if I use only one capture group
Regex := TRegEx.Create('(?P<time>\d{1,2}:\d{1,2})');
The first dialog shows “2” and the second dialog will show the time “00:00” as expected.
However this would be a bit limiting if only one named capture group was allowed, but thats not the case… If I change the capture group name to for example “atime”.
var
Regex: TRegEx;
M: TMatch;
begin
Regex := TRegEx.Create('(?P<atime>\d{1,2}:\d{1,2})(?P<judge>.{1,3})');
M := Regex.Match('00:00 X1 90 55KENNY BENNY');
ShowMessage(IntToStr(M.Groups.Count));
ShowMessage(M.Groups['atime'].Value);
end;
I’ll get “3” and “00:00”, just as expected. Is there reserved words I cannot use? I don’t think so because in my real example I’ve tried completely random names. I just cannot figure out what causes this behaviour.
When pcre_get_stringnumber does not find the name,
PCRE_ERROR_NOSUBSTRINGis returned.PCRE_ERROR_NOSUBSTRINGis defined in RegularExpressionsAPI asPCRE_ERROR_NOSUBSTRING = -7.Some testing shows that
pcre_get_stringnumberreturnsPCRE_ERROR_NOSUBSTRINGfor every name that has the first letter in the range ofktozand that range is dependent of the first letter injudge. Changingjudgeto something else changes the range.As i see it there is at lest two bugs involved here. One in
pcre_get_stringnumberand one in TGroupCollection.GetItem that needs to raise a proper exception instead ofSRegExIndexOutOfBounds