Re: Regular expression question
Andrei Bârsan <[email protected]>
| Newsgroups | gmane.comp.graphics.crystalspace.devel |
|---|---|
| Message-ID | <[email protected]> |
Hello Mat,
Thanks for the detailed response! Also, the first error you pointed out
was just me not paying attention. It was probably hastily copied from a
pointer initialization someplace else. And thanks for pointing out the
second thing. Should I just be careful and cast to an unsigned int and
use %u from now on?
Regards,
Andrei
On 19.08.2012 16:17, Mat Sutcliffe wrote:
> Hi Andrei,
>
> POSIX regex, which csRegExpMatcher uses, does not return multiple
> matches. It finds the first match in the string and then stops. The
> array of matches is populated with sub-matches from parenthesized
> subexpressions in the pattern.
>
> If you replace your pattern "el" with "(el)" you should get an array
> with one member. If you use the pattern "((e)(l))" you should get
> three members. But I think that because of a bug in
> csRegExpMatcher::Match, those three members will correspond to the
> substrings "el", "el" and "e". To fix the bug, the array of regmatch_t
> structures passed to regexec should have length regex.re_nsub+1. Then
> matching the pattern "el" would give one array member, matching "(el)"
> would give two members, and "((e)(l))" four members. This is a
> breaking API change, but would make regexes work as intended. As it is
> currently, you always lose the final subexpression match.
>
> You could implement multiple matches in the way you expected it to
> work originally, simply by calling Match again with the offset
> obtained from the previous call to Match.
>
> Another couple of problems I can see in your pasted code:
>
> csRegExpMatcher matcher = csRegExpMatcher("el", true);
> This says to construct two matchers and then copy one into the other.
> Maybe your compiler optimises this out, maybe not. Cleaner to just do
> this:
> csRegExpMatcher matcher ("el", true);
>
> printf("Found %d matches!\n", result.GetSize());
> csArray::GetSize returns a size_t, which is an unsigned integer type,
> but in printf with the %d format specifier you are treating it as a
> signed integer, with undefined consequences.
> This should be:
> printf("Found %u matches!\n", static_cast<unsigned
> int>(result.GetSize()));
> csRegExpMatch::startOffset is also a size_t, so the same applies to
> where you print the offsets a couple lines below.
> Not sure if the cast is strictly necessary, but better to be safe as
> size_t is not guaranteed to be the same number of bits as an unsigned
> int. ISO C defines %zu as printf format specifier for size_t, but MSVC
> ignores this and uses %Iu (uppercase i, lowercase u), so the "proper"
> way might be to use the preprocessor to select the appropriate
> specifier, and then you wouldn't need the cast. That preprocessor guff
> could be a candidate for inclusion in cssysdef.h.
>
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/