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/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.