I am trying to get total duration of a youtube playlist using youtube data api. I download response from, for example, http://gdata.youtube.com/feeds/api/playlists/63F0C78739B09958 and my idea is to iterate over each <yt:duration='xxx'/>
occurences where xxx
is each video duration in seconds, and sum them up to get total playlist runtime.
For getting each i use CAtlRegExp
with the following string:
<yt:duration seconds='{[0-9]+}'/>
however it matches only the first occurence, not any of the rest (referring to the source code pasted below, the loop iterates only once).
I tried some other regex strings like
(<yt:duration seconds='{[0-9]+}'/>)
(<yt:duration seconds='{[0-9]+}'/>)*
however they didn't work either (the same reason).
Here is an extract from source code, where the for loop only iterates once because mcDuration.m_uNumGroups
equals to 1
:
//get video duration
CAtlRegExp<> reDurationFinder;
CAtlREMatchContext<> mcDuration;
REParseError status = reDurationFinder.Parse(_T("<yt:duration seconds='{[0-9]+}'/>"));
if ( status != REPARSE_ERROR_OK )
{
// Unexpected error.
return false;
}
if ( !reDurationFinder.Match(sFeed, &mcDuration) ) //i checked it with debug, sFeed contains full response from youtube data api
{
//cannot find video url
return false;
}
m_nLengthInSeconds = 0;
for ( UINT nGroupIndex = 0; nGroupIndex < mcDuration.m_uNumGroups; ++nGroupIndex )
{
const CAtlREMatchContext<>::RECHAR* szStart = 0;
const CAtlREMatchContext<>::RECHAR* szEnd = 0;
mcDuration.GetMatch(nGroupIndex, &szStart, &szEnd);
ptrdiff_t nLength = szEnd - szStart;
m_nLengthInSeconds += _ttoi(CString(szStart, nLength));
}
How can I make CAtlRegExp
match all of the occurences of <yt:duration ...
?
You will always have the first (next) occurrence only. To find others you need to keep Match
'ing in a loop until no more occurrences found.
for(; ; )
{
CAtlREMatchContext<> MatchContext;
pszNextText = NULL;
if(!Expression.Match(pszText, &MatchContext, &pszNextText))
break;
// Here you process the found occurrence
pszText = pszNextText;
}