📄 reimpl2.h
字号:
if( first )
str.replace( itstrpos, itstrlen, itsubpos2, itsublen2 );
else
str.insert( itstrpos, itsubpos2, itsublen2 );
sublen = std::distance( itsubpos2, itsublen2 );
break;
case subst_node::SUBST_BACKREF:
switch( isubst->subst_backref )
{
case subst_node::PREMATCH:
itsubpos1 = results.backref_str().begin();
itsublen1 = itsubpos1;
std::advance( itsublen1, sublen = results.rstart() );
break;
case subst_node::POSTMATCH:
itsubpos1 = results.backref_str().begin();
std::advance( itsubpos1, results.rstart() + results.rlength() );
itsublen1 = results.backref_str().end();
break;
default:
itsubpos1 = results.backref_str().begin();
std::advance( itsubpos1, results.rstart( isubst->subst_backref ) );
itsublen1 = itsubpos1;
std::advance( itsublen1, results.rlength( isubst->subst_backref ) );
break;
}
if( first )
str.replace( itstrpos, itstrlen, itsubpos1, itsublen1 );
else
str.insert( itstrpos, itsubpos1, itsublen1 );
sublen = std::distance( itsubpos1, itsublen1 );
break;
case subst_node::SUBST_OP:
switch( isubst->op )
{
case subst_node::UPPER_ON:
rest = UPPER;
break;
case subst_node::UPPER_NEXT:
next = UPPER;
break;
case subst_node::LOWER_ON:
rest = LOWER;
break;
case subst_node::LOWER_NEXT:
next = LOWER;
break;
case subst_node::ALL_OFF:
rest = NIL;
break;
default:
__assume( 0 );
}
continue; // jump to the next item in the list
default:
__assume( 0 );
}
first = false;
// Are we upper- or lower-casing this string?
if( rest )
{
typename std::basic_string<CH, TR, AL>::iterator istart = str.begin();
std::advance( istart, strpos );
typename std::basic_string<CH, TR, AL>::const_iterator istop = istart;
std::advance( istop, sublen );
switch( rest )
{
case UPPER:
regex_toupper( istart, istop );
break;
case LOWER:
regex_tolower( istart, istop );
break;
default:
__assume( 0 );
}
}
// Are we upper- or lower-casing the next character?
if( next )
{
switch( next )
{
case UPPER:
str[strpos] = regex_toupper( str[strpos] );
break;
case LOWER:
str[strpos] = regex_tolower( str[strpos] );
break;
default:
__assume( 0 );
}
next = NIL;
}
strpos += sublen;
}
// If *first* is still true, then we never called str.replace, and the substitution
// string is empty. Erase the part of the string that the pattern matched.
if( first )
str.erase( strpos, strlen );
// return length of the substitution
return strpos - old_strpos;
}
template< typename CH, typename TR, typename AL >
static size_t _Do_subst(
rpattern_type const & pat,
std::basic_string<CH, TR, AL> & str,
basic_subst_results<CH, TR, AL> & results,
size_type pos,
size_type len )
{
typedef std::basic_string<CH, TR, AL> string_type;
results.m_pbackref_str = pat._save_backrefs() ? &( results.m_backref_str = str ) : &str;
results.ibegin = results.m_pbackref_str->begin();
size_t csubst = 0;
size_type stop_offset = results.m_pbackref_str->size();
if( len != rpattern_type::npos )
stop_offset = (std::min)( size_t( pos + len ), stop_offset );
match_param<CI> param( results.ibegin, results.ibegin, & results.m_rgbackrefs );
std::advance( param.istart, pos );
std::advance( param.istop, stop_offset );
param.ibegin = param.istart;
if( GLOBAL & pat.flags() )
{
bool const fAll = ( ALLBACKREFS == ( ALLBACKREFS & pat.flags() ) );
bool const fFirst = ( FIRSTBACKREFS == ( FIRSTBACKREFS & pat.flags() ) );
backref_vector rgtempbackrefs; // temporary vector used if fsave_backrefs
size_type pos_offset = 0; // keep track of how much the backref_str and
// the current string are out of sync
while( _Do_match( pat, param, false ) )
{
backref_type const & br = results.m_rgbackrefs[0];
++csubst;
size_type match_length = std::distance( br.first, br.second );
pos = std::distance( results.ibegin, br.first );
size_type subst_length = _Do_subst_internal( str, results, pat, pos + pos_offset, match_length );
if( pat._save_backrefs() )
{
pos += match_length;
pos_offset += ( subst_length - match_length );
// Handle specially the backref flags
if( fFirst )
rgtempbackrefs.push_back( br );
else if( fAll )
rgtempbackrefs.insert( rgtempbackrefs.end(),
param.prgbackrefs->begin(),
param.prgbackrefs->end() );
else
rgtempbackrefs.swap( *param.prgbackrefs );
}
else
{
pos += subst_length;
stop_offset += ( subst_length - match_length );
results.ibegin = results.m_pbackref_str->begin();
// we're not saving backref information, so we don't
// need to do any special backref maintenance here
}
// prevent a pattern that matches 0 characters from matching
// again at the same point in the string
param.no0len = ( 0 == match_length );
param.istart = results.ibegin;
std::advance( param.istart, pos ); // ineffecient for bidirectional iterators.
param.istop = results.ibegin;
std::advance( param.istop, stop_offset ); // ineffecient for bidirectional iterators.
}
// If we did special backref handling, swap the backref vectors
if( pat._save_backrefs() )
{
param.prgbackrefs->swap( rgtempbackrefs );
}
else if( ! ( *param.prgbackrefs )[0].matched )
{
param.prgbackrefs->clear();
}
}
else if( _Do_match( pat, param, false ) )
{
backref_type const & br = results.m_rgbackrefs[0];
++csubst;
_Do_subst_internal(
str, results, pat,
std::distance( results.ibegin, br.first ),
std::distance( br.first, br.second ) );
results.ibegin = results.m_pbackref_str->begin();
}
if( NOBACKREFS == ( pat.flags() & NOBACKREFS ) )
{
param.prgbackrefs->clear();
}
return csubst;
}
};
template< typename CI >
REGEX_NOINLINE bool matcher_helper<CI>::_Do_match_with_stack( rpattern_type const & pat, match_param<CI> & param, bool const use_null )
{
unsafe_stack s;
param.pstack = &s;
return _Do_match_impl( pat, param, use_null );
}
//
// Some helper functions needed by process_escapes
//
template< typename CH >
inline bool regex_isxdigit( CH ch )
{
return ( REGEX_CHAR(CH,'0') <= ch && REGEX_CHAR(CH,'9') >= ch )
|| ( REGEX_CHAR(CH,'a') <= ch && REGEX_CHAR(CH,'f') >= ch )
|| ( REGEX_CHAR(CH,'A') <= ch && REGEX_CHAR(CH,'F') >= ch );
}
template< typename CH >
inline int regex_xdigit2int( CH ch )
{
if( REGEX_CHAR(CH,'a') <= ch && REGEX_CHAR(CH,'f') >= ch )
return ch - REGEX_CHAR(CH,'a') + 10;
if( REGEX_CHAR(CH,'A') <= ch && REGEX_CHAR(CH,'F') >= ch )
return ch - REGEX_CHAR(CH,'A') + 10;
return ch - REGEX_CHAR(CH,'0');
}
} // namespace detail
// --------------------------------------------------------------------------
//
// Function: process_escapes
//
// Description: Turn the escape sequnces \f \n \r \t \v \\ into their
// ASCII character equivalents. Also, optionally process
// perl escape sequences.
//
// Returns: void
//
// Arguments: str - the string to process
// fPattern - true if the string is to be processed as a regex
//
// Notes: When fPattern is true, the perl escape sequences are not
// processed. If there is an octal or hex excape sequence, we
// don't want to turn it into a regex metacharacter here. We
// leave it unescaped so the regex parser correctly interprests
// it as a character literal.
//
// History: 8/1/2001 - ericne - Created
//
// --------------------------------------------------------------------------
template< typename CH, typename TR, typename AL >
inline void process_escapes( std::basic_string<CH, TR, AL> & str, bool fPattern ) //throw()
{
typedef typename std::basic_string<CH, TR, AL>::size_type size_type;
size_type i = 0;
size_type const npos = std::basic_string<CH, TR, AL>::npos;
if( str.empty() )
return;
while( npos != ( i = str.find( REGEX_CHAR(CH,'\\'), i ) ) )
{
if( str.size() - 1 == i )
return;
switch( str[i+1] )
{
case REGEX_CHAR(CH,'a'):
str.replace( i, 2, 1, REGEX_CHAR(CH,'\a') );
break;
case REGEX_CHAR(CH,'b'):
if( ! fPattern )
str.replace( i, 2, 1, REGEX_CHAR(CH,'\b') );
else
++i;
break;
case REGEX_CHAR(CH,'e'):
str.replace( i, 2, 1, CH( 27 ) );
break;
case REGEX_CHAR(CH,'f'):
str.replace( i, 2, 1, REGEX_CHAR(CH,'\f') );
break;
case REGEX_CHAR(CH,'n'):
str.replace( i, 2, 1, REGEX_CHAR(CH,'\n') );
break;
case REGEX_CHAR(CH,'r'):
str.replace( i, 2, 1, REGEX_CHAR(CH,'\r') );
break;
case REGEX_CHAR(CH,'t'):
str.replace( i, 2, 1, REGEX_CHAR(CH,'\t') );
break;
case REGEX_CHAR(CH,'v'):
str.replace( i, 2, 1, REGEX_CHAR(CH,'\v') );
break;
case REGEX_CHAR(CH,'\\'):
if( fPattern )
{
if( i+3 < str.size() && REGEX_CHAR(CH,'\\') == str[i+2] && REGEX_CHAR(CH,'\\') == str[i+3] )
str.erase( i, 2 );
++i;
}
else
str.erase( i, 1 );
break;
case REGEX_CHAR(CH,'0'): case REGEX_CHAR(CH,'1'): case REGEX_CHAR(CH,'2'): case REGEX_CHAR(CH,'3'):
case REGEX_CHAR(CH,'4'): case REGEX_CHAR(CH,'5'): case REGEX_CHAR(CH,'6'): case REGEX_CHAR(CH,'7'):
if( ! fPattern )
{
size_t j=i+2;
CH ch = CH( str[i+1] - REGEX_CHAR(CH,'0') );
for( ; j-i < 4 && j < str.size() && REGEX_CHAR(CH,'0') <= str[j] && REGEX_CHAR(CH,'7') >= str[j]; ++j )
ch = CH( ch * 8 + ( str[j] - REGEX_CHAR(CH,'0') ) );
str.replace( i, j-i, 1, ch );
}
break;
case REGEX_CHAR(CH,'x'):
if( ! fPattern )
{
CH ch = 0;
size_t j=i+2;
for( ; j-i < 4 && j < str.size() && detail::regex_isxdigit( str[j] ); ++j )
ch = CH( ch * 16 + detail::regex_xdigit2int( str[j] ) );
str.replace( i, j-i, 1, ch );
}
break;
case REGEX_CHAR(CH,'c'):
if( ! fPattern && i+2 < str.size() )
{
CH ch = str[i+2];
if( REGEX_CHAR(CH,'a') <= ch && REGEX_CHAR(CH,'z') >= ch )
ch = detail::regex_toupper( ch );
str.replace( i, 3, 1, CH( ch ^ 0x40 ) );
}
break;
default:
if( fPattern )
++i;
else
str.erase( i, 1 );
break;
}
++i;
if( str.size() <= i )
return;
}
}
#ifndef _MSC_VER
#undef __assume
#endif
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -