diff --git a/stl/inc/regex b/stl/inc/regex
index 3366345c261..aad62172c2a 100644
--- a/stl/inc/regex
+++ b/stl/inc/regex
@@ -1657,6 +1657,17 @@ public:
           _Longest((_Re->_Flags & _Fl_longest) && !(_Mf & regex_constants::match_any)), _Traits(_Tr) {
         _Loop_vals.resize(_Re->_Loops);
         _Adl_verify_range(_Pfirst, _Plast);
+        if (_Re->_Flags & _Fl_begin_needs_w) {
+            _Char_class_w = _Lookup_char_class(static_cast<_Elem>('W'));
+        }
+
+        if (_Re->_Flags & _Fl_begin_needs_s) {
+            _Char_class_s = _Lookup_char_class(static_cast<_Elem>('S'));
+        }
+
+        if (_Re->_Flags & _Fl_begin_needs_d) {
+            _Char_class_d = _Lookup_char_class(static_cast<_Elem>('D'));
+        }
     }
 
     void _Setf(regex_constants::match_flag_type _Mf) { // set specified flags
@@ -1739,7 +1750,7 @@ private:
     bool _Do_rep(_Node_rep*, bool, int);
     bool _Do_rep_first(_Node_rep*);
     bool _Find_first_inner_capture_group(_Node_base*, _Loop_vals_v2_t*);
-    bool _Do_class(_Node_base*);
+    _It _Do_class(_Node_base*, _It);
     bool _Match_pat(_Node_base*);
     bool _Better_match();
     bool _Is_wbound() const;
@@ -1758,6 +1769,9 @@ private:
     bool _Full;
     long _Max_complexity_count;
     long _Max_stack_count;
+    typename _RxTraits::char_class_type _Char_class_w{};
+    typename _RxTraits::char_class_type _Char_class_s{};
+    typename _RxTraits::char_class_type _Char_class_d{};
 
 public:
     _Matcher2& operator=(const _Matcher2&) = delete;
@@ -3679,9 +3693,10 @@ _BidIt _Lookup_coll2(_Elem _First_ch, _BidIt _First, const _BidIt _Last, const _
 }
 
 template <class _BidIt, class _Elem, class _RxTraits, class _It, class _Alloc>
-bool _Matcher2<_BidIt, _Elem, _RxTraits, _It, _Alloc>::_Do_class(_Node_base* _Nx) { // apply bracket expression
+_It _Matcher2<_BidIt, _Elem, _RxTraits, _It, _Alloc>::_Do_class(_Node_base* _Nx, _It _First) {
+    // apply bracket expression
     bool _Found;
-    _Elem _Ch = *_Tgt_state._Cur;
+    _Elem _Ch = *_First;
     if (_Sflags & regex_constants::icase) {
         _Ch = _Traits.translate_nocase(_Ch);
     } else if (_Sflags & regex_constants::collate) {
@@ -3689,13 +3704,13 @@ bool _Matcher2<_BidIt, _Elem, _RxTraits, _It, _Alloc>::_Do_class(_Node_base* _Nx
     }
     const auto _UCh = static_cast<typename _RxTraits::_Uelem>(_Ch);
 
-    _It _Res0 = _Tgt_state._Cur;
+    _It _Res0 = _First;
     ++_Res0;
     _It _Resx;
     _Node_class<_Elem, _RxTraits>* _Node = static_cast<_Node_class<_Elem, _RxTraits>*>(_Nx);
     if (_Node->_Coll
-        && (_Resx = _STD _Lookup_coll2(_Ch, _Tgt_state._Cur, _End, _Node->_Coll, _Traits, _Sflags))
-               != _Tgt_state._Cur) { // check for collation element
+        && (_Resx = _STD _Lookup_coll2(_Ch, _First, _End, _Node->_Coll, _Traits, _Sflags))
+               != _First) { // check for collation element
         _Res0  = _Resx;
         _Found = true;
     } else if (_Node->_Ranges
@@ -3715,14 +3730,11 @@ bool _Matcher2<_BidIt, _Elem, _RxTraits, _It, _Alloc>::_Do_class(_Node_base* _Nx
         _Found = true;
     } else if (_Node->_Equiv && _STD _Lookup_equiv2(_Ch, _Node->_Equiv, _Traits)) {
         _Found = true;
-    } else if ((_Node->_Flags & _Fl_class_negated_w)
-               && !_Traits.isctype(_Ch, _Lookup_char_class(static_cast<_Elem>('W')))) {
+    } else if ((_Node->_Flags & _Fl_class_negated_w) && !_Traits.isctype(_Ch, _Char_class_w)) {
         _Found = true;
-    } else if ((_Node->_Flags & _Fl_class_negated_s)
-               && !_Traits.isctype(_Ch, _Lookup_char_class(static_cast<_Elem>('S')))) {
+    } else if ((_Node->_Flags & _Fl_class_negated_s) && !_Traits.isctype(_Ch, _Char_class_s)) {
         _Found = true;
-    } else if ((_Node->_Flags & _Fl_class_negated_d)
-               && !_Traits.isctype(_Ch, _Lookup_char_class(static_cast<_Elem>('D')))) {
+    } else if ((_Node->_Flags & _Fl_class_negated_d) && !_Traits.isctype(_Ch, _Char_class_d)) {
         _Found = true;
     } else {
         _Found = false;
@@ -3731,10 +3743,9 @@ bool _Matcher2<_BidIt, _Elem, _RxTraits, _It, _Alloc>::_Do_class(_Node_base* _Nx
     const bool _Negated = (_Node->_Flags & _Fl_negate) != 0;
 
     if (_Found == _Negated) {
-        return false;
-    } else { // record result
-        _Tgt_state._Cur = _Res0;
-        return true;
+        return _First;
+    } else {
+        return _Res0;
     }
 }
 
@@ -3868,7 +3879,12 @@ bool _Matcher2<_BidIt, _Elem, _RxTraits, _It, _Alloc>::_Match_pat(_Node_base* _N
 
         case _N_class:
             { // check for bracket expression match
-                _Failed = _Tgt_state._Cur == _End || !_Do_class(_Nx);
+                _It _Res;
+                if (_Tgt_state._Cur != _End && (_Res = _Do_class(_Nx, _Tgt_state._Cur)) != _Tgt_state._Cur) {
+                    _Tgt_state._Cur = _Res;
+                } else {
+                    _Failed = true;
+                }
                 break;
             }
 
@@ -4046,56 +4062,10 @@ _BidIt _Matcher2<_BidIt, _Elem, _RxTraits, _It, _Alloc>::_Skip(_BidIt _First_arg
 
         case _N_class:
             { // check for string match
-                for (; _First_arg != _Last; ++_First_arg) { // look for starting match
-                    bool _Found;
-                    _Elem _Ch = *_First_arg;
-                    if (_Sflags & regex_constants::icase) {
-                        _Ch = _Traits.translate_nocase(_Ch);
-                    } else if (_Sflags & regex_constants::collate) {
-                        _Ch = _Traits.translate(_Ch);
-                    }
-                    const auto _UCh = static_cast<typename _RxTraits::_Uelem>(_Ch);
-
-                    _Node_class<_Elem, _RxTraits>* _Node = static_cast<_Node_class<_Elem, _RxTraits>*>(_Nx);
-
-                    if (_Node->_Coll
-                        && _STD _Lookup_coll2(_Ch, _First_arg, _Last, _Node->_Coll, _Traits, _Sflags) != _First_arg) {
-                        _Found = true;
-                    } else if (_Node->_Ranges
-                               && (_Sflags & regex_constants::collate
-                                       ? _STD _Lookup_collating_range(_Ch, _Node->_Ranges, _Traits)
-                                       : _STD _Lookup_range(_UCh, _Node->_Ranges))) {
-                        _Found = true;
-                    } else if (_UCh < _Bmp_max) {
-                        _Found = _Node->_Small && _Node->_Small->_Find(_UCh);
-                    } else if (_Node->_Large
-                               && _STD find(_Node->_Large->_Str(), _Node->_Large->_Str() + _Node->_Large->_Size(), _Ch)
-                                      != _Node->_Large->_Str() + _Node->_Large->_Size()) {
-                        _Found = true;
-                    } else if (_Node->_Classes != typename _RxTraits::char_class_type{}
-                               && _Traits.isctype(_Ch, _Node->_Classes)) {
-                        _Found = true;
-                    } else if ((_Node->_Flags & _Fl_class_cl_all_bits)
-                               && _Traits.isctype(_Ch, static_cast<typename _RxTraits::char_class_type>(-1))) {
-                        _Found = true;
-                    } else if (_Node->_Equiv && _STD _Lookup_equiv2(_Ch, _Node->_Equiv, _Traits)) {
-                        _Found = true;
-                    } else if ((_Node->_Flags & _Fl_class_negated_w)
-                               && !_Traits.isctype(_Ch, _Lookup_char_class(static_cast<_Elem>('W')))) {
-                        _Found = true;
-                    } else if ((_Node->_Flags & _Fl_class_negated_s)
-                               && !_Traits.isctype(_Ch, _Lookup_char_class(static_cast<_Elem>('S')))) {
-                        _Found = true;
-                    } else if ((_Node->_Flags & _Fl_class_negated_d)
-                               && !_Traits.isctype(_Ch, _Lookup_char_class(static_cast<_Elem>('D')))) {
-                        _Found = true;
-                    } else {
-                        _Found = false;
-                    }
+                _Node_class<_Elem, _RxTraits>* _Node = static_cast<_Node_class<_Elem, _RxTraits>*>(_Nx);
 
-                    const bool _Negated = (_Node->_Flags & _Fl_negate) != 0;
-
-                    if (_Found != _Negated) {
+                for (; _First_arg != _Last; ++_First_arg) { // look for starting match
+                    if (_Do_class(_Node, _First_arg) != _First_arg) {
                         return _First_arg;
                     }
                 }