mirror of
https://github.com/boostorg/regex.git
synced 2025-07-21 00:02:41 +02:00
Added support for \g \K and \R.
[SVN r52592]
This commit is contained in:
@ -720,7 +720,89 @@ escape_type_class_jump:
|
||||
return true;
|
||||
}
|
||||
fail(regex_constants::error_ctype, m_position - m_base);
|
||||
return false;
|
||||
}
|
||||
case regex_constants::escape_type_reset_start_mark:
|
||||
if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
|
||||
{
|
||||
re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));
|
||||
pb->index = -5;
|
||||
this->m_pdata->m_data.align();
|
||||
++m_position;
|
||||
return true;
|
||||
}
|
||||
goto escape_type_class_jump;
|
||||
case regex_constants::escape_type_line_ending:
|
||||
if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
|
||||
{
|
||||
const charT* e = get_escape_R_string<charT>();
|
||||
const charT* old_position = m_position;
|
||||
const charT* old_end = m_end;
|
||||
const charT* old_base = m_base;
|
||||
m_position = e;
|
||||
m_base = e;
|
||||
m_end = e + traits::length(e);
|
||||
bool r = parse_all();
|
||||
m_position = ++old_position;
|
||||
m_end = old_end;
|
||||
m_base = old_base;
|
||||
return r;
|
||||
}
|
||||
goto escape_type_class_jump;
|
||||
case regex_constants::escape_type_extended_backref:
|
||||
if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
|
||||
{
|
||||
bool have_brace = false;
|
||||
bool negative = false;
|
||||
if(++m_position == m_end)
|
||||
{
|
||||
fail(regex_constants::error_escape, m_position - m_base);
|
||||
return false;
|
||||
}
|
||||
// maybe have \g{ddd}
|
||||
if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)
|
||||
{
|
||||
if(++m_position == m_end)
|
||||
{
|
||||
fail(regex_constants::error_escape, m_position - m_base);
|
||||
return false;
|
||||
}
|
||||
have_brace = true;
|
||||
}
|
||||
negative = (*m_position == static_cast<charT>('-'));
|
||||
if((negative) && (++m_position == m_end))
|
||||
{
|
||||
fail(regex_constants::error_escape, m_position - m_base);
|
||||
return false;
|
||||
}
|
||||
const charT* pc = m_position;
|
||||
int i = this->m_traits.toi(pc, m_end, 10);
|
||||
if(negative)
|
||||
i = 1 + m_mark_count - i;
|
||||
if((i > 0) && (this->m_backrefs & (1u << (i-1))))
|
||||
{
|
||||
m_position = pc;
|
||||
re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_backref, sizeof(re_brace)));
|
||||
pb->index = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
fail(regex_constants::error_backref, m_position - m_end);
|
||||
return false;
|
||||
}
|
||||
m_position = pc;
|
||||
if(have_brace)
|
||||
{
|
||||
if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))
|
||||
{
|
||||
fail(regex_constants::error_escape, m_position - m_base);
|
||||
return false;
|
||||
}
|
||||
++m_position;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
goto escape_type_class_jump;
|
||||
case regex_constants::escape_type_control_v:
|
||||
if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
|
||||
goto escape_type_class_jump;
|
||||
@ -1499,7 +1581,7 @@ charT basic_regex_parser<charT, traits>::unescape_character()
|
||||
int i = this->m_traits.toi(m_position, m_end, 16);
|
||||
if((m_position == m_end)
|
||||
|| (i < 0)
|
||||
|| ((std::numeric_limits<charT>::is_specialized) && (charT(i) > (std::numeric_limits<charT>::max)()))
|
||||
|| ((std::numeric_limits<charT>::is_specialized) && (i > (int)(std::numeric_limits<charT>::max)()))
|
||||
|| (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))
|
||||
{
|
||||
fail(regex_constants::error_badbrace, m_position - m_base);
|
||||
|
@ -230,13 +230,13 @@ public:
|
||||
m_null.matched = false;
|
||||
}
|
||||
|
||||
void BOOST_REGEX_CALL set_second(BidiIterator i, size_type pos, bool m = true)
|
||||
void BOOST_REGEX_CALL set_second(BidiIterator i, size_type pos, bool m = true, bool escape_k = false)
|
||||
{
|
||||
pos += 2;
|
||||
BOOST_ASSERT(m_subs.size() > pos);
|
||||
m_subs[pos].second = i;
|
||||
m_subs[pos].matched = m;
|
||||
if(pos == 2)
|
||||
if((pos == 2) && !escape_k)
|
||||
{
|
||||
m_subs[0].first = i;
|
||||
m_subs[0].matched = (m_subs[0].first != m_subs[0].second);
|
||||
@ -284,11 +284,18 @@ public:
|
||||
m_subs[n].matched = false;
|
||||
}
|
||||
}
|
||||
void BOOST_REGEX_CALL set_first(BidiIterator i, size_type pos)
|
||||
void BOOST_REGEX_CALL set_first(BidiIterator i, size_type pos, bool escape_k = false)
|
||||
{
|
||||
BOOST_ASSERT(pos+2 < m_subs.size());
|
||||
if(pos)
|
||||
if(pos || escape_k)
|
||||
{
|
||||
m_subs[pos+2].first = i;
|
||||
if(escape_k)
|
||||
{
|
||||
m_subs[1].second = i;
|
||||
m_subs[1].matched = (m_subs[1].first != m_subs[1].second);
|
||||
}
|
||||
}
|
||||
else
|
||||
set_first(i);
|
||||
}
|
||||
|
@ -205,7 +205,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_imp()
|
||||
verify_options(re.flags(), m_match_flags);
|
||||
if(0 == match_prefix())
|
||||
return false;
|
||||
return m_result[0].second == last;
|
||||
return (m_result[0].second == last) && (m_result[0].first == base);
|
||||
|
||||
#if defined(BOOST_REGEX_NON_RECURSIVE) && !defined(BOOST_NO_EXCEPTIONS)
|
||||
}
|
||||
|
@ -213,7 +213,7 @@ void perl_matcher<BidiIterator, Allocator, traits>::extend_stack()
|
||||
template <class BidiIterator, class Allocator, class traits>
|
||||
inline void perl_matcher<BidiIterator, Allocator, traits>::push_matched_paren(int index, const sub_match<BidiIterator>& sub)
|
||||
{
|
||||
BOOST_ASSERT(index);
|
||||
//BOOST_ASSERT(index);
|
||||
saved_matched_paren<BidiIterator>* pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);
|
||||
--pmp;
|
||||
if(pmp < m_stack_base)
|
||||
@ -404,6 +404,13 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_startmark()
|
||||
break;
|
||||
}
|
||||
}
|
||||
case -5:
|
||||
{
|
||||
push_matched_paren(0, (*m_presult)[0]);
|
||||
m_presult->set_first(position, 0, true);
|
||||
pstate = pstate->next.p;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
BOOST_ASSERT(index > 0);
|
||||
@ -911,8 +918,8 @@ bool perl_matcher<BidiIterator, Allocator, traits>::unwind_paren(bool have_match
|
||||
// restore previous values if no match was found:
|
||||
if(have_match == false)
|
||||
{
|
||||
m_presult->set_first(pmp->sub.first, pmp->index);
|
||||
m_presult->set_second(pmp->sub.second, pmp->index, pmp->sub.matched);
|
||||
m_presult->set_first(pmp->sub.first, pmp->index, pmp->index == 0);
|
||||
m_presult->set_second(pmp->sub.second, pmp->index, pmp->sub.matched, pmp->index == 0);
|
||||
}
|
||||
#ifdef BOOST_REGEX_MATCH_EXTRA
|
||||
//
|
||||
|
@ -51,8 +51,8 @@ public:
|
||||
template <class A>
|
||||
void restore(match_results<BidiIterator, A>& w)
|
||||
{
|
||||
w.set_first(sub.first, index);
|
||||
w.set_second(sub.second, index, sub.matched);
|
||||
w.set_first(sub.first, index, index == 0);
|
||||
w.set_second(sub.second, index, sub.matched, index == 0);
|
||||
}
|
||||
const sub_match<BidiIterator>& get() { return sub; }
|
||||
};
|
||||
@ -209,6 +209,17 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_startmark()
|
||||
break;
|
||||
}
|
||||
}
|
||||
case -5:
|
||||
{
|
||||
// Reset start of $0, since we have a \K escape
|
||||
backup_subex<BidiIterator> sub(*m_presult, 0);
|
||||
m_presult->set_first(position, 0, true);
|
||||
pstate = pstate->next.p;
|
||||
r = match_all_states();
|
||||
if(r == false)
|
||||
sub.restore(*m_presult);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
BOOST_ASSERT(index > 0);
|
||||
|
@ -317,6 +317,28 @@ int global_toi(const charT*& p1, const charT* p2, int radix, const traits& t)
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class charT>
|
||||
inline const charT* get_escape_R_string()
|
||||
{
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4309)
|
||||
#endif
|
||||
static const charT e1[] = { '(', '?', '>', '\x0D', '\x0A', '?',
|
||||
'|', '[', '\x0A', '\x0B', '\x0C', '\x85', '\\', 'x', '{', '2', '0', '2', '8', '}',
|
||||
'\\', 'x', '{', '2', '0', '2', '9', '}', ']', ')' };
|
||||
static const charT e2[] = { '(', '?', '>', '\x0D', '\x0A', '?',
|
||||
'|', '[', '\x0A', '\x0B', '\x0C', '\x85', ']', ')' };
|
||||
|
||||
charT c = static_cast<charT>(0x2029u);
|
||||
bool b = (static_cast<unsigned>(c) == 0x2029u);
|
||||
|
||||
return (b ? e1 : e2);
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
}
|
||||
|
||||
} // re_detail
|
||||
} // boost
|
||||
|
||||
|
@ -92,8 +92,11 @@ static const escape_syntax_type escape_type_G = 52; /
|
||||
static const escape_syntax_type escape_type_property = 54; // for \p
|
||||
static const escape_syntax_type escape_type_not_property = 55; // for \P
|
||||
static const escape_syntax_type escape_type_named_char = 56; // for \N
|
||||
static const escape_syntax_type escape_type_extended_backref = 57; // for \g
|
||||
static const escape_syntax_type escape_type_reset_start_mark = 58; // for \K
|
||||
static const escape_syntax_type escape_type_line_ending = 59; // for \R
|
||||
|
||||
static const escape_syntax_type syntax_max = 57;
|
||||
static const escape_syntax_type syntax_max = 60;
|
||||
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user