Re: Regular expression question
Mat Sutcliffe <[email protected]>
| Newsgroups | gmane.comp.graphics.crystalspace.devel |
|---|---|
| Message-ID | <CACE5Bz+x-f7uHSdBHz0gEVOF_nvDMyzkr--GDZn_6owz4FHYdA@mail.gmail.com> |
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.
On 18 August 2012 20:56, Andrei Bârsan <[email protected]> wrote:
> Hello,
>
> I've been trying to implement some regular expression processing, but
> I'm having problems getting any matches. Here is what I'm trying to do:
> http://pastebin.com/szuNMkcu. It's returning csRxNoError (which is
> returned when there's no compile error, and there are matches), but the
> result array doesn't get populated with any matches.
>
------------------------------------------------------------------------------
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/
_______________________________________________
Crystal-develop mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/crystal-develop