You can achieve this with a negative lookahead, which will tell your expression to either 1. eat one character, or 2. match the special sequence, then rinse and repeat:
<(\w+)\s*(?:(?:(?:(?!class=|id=|name=)[^>]))*((?:class|id|name)=['"][^'"]*['"]\s*)?)+>
Explanation:
<(\w+)\s*
(match open of tag and tagname)
(?:
(begin enclosure of main construct (note that it doesn't remember matches))
(?:(?:(?!class=|id=|name=)[^>]))*
(look ahead for no special token, then eat one character, repeat as many times possible, don't bother to remember anything)
((?:class|id|name)=['"][^'"]*['"])\s*?
(lookahead failed, so special token ahead, let's eat it! note the regular, 'remembering' parens)
)+
(end enclosure of main construct; repeat it, it'll match once for each special token)
>
(end of tag)
At this point you might have the matches you need, if your regex flavor supports multiple matches per group. In .NET for example, you'd have something similar to this: $1 = 'a', $2[0]='class="someClass"', $2[1]='id="someId"', etc.
But if you find that only the last match is remembered, you may have to simply repeat the main construct for each token you want to match, like so: (matches will be $1-$4)
<(\w+)\s*(?:(?:(?:(?!class=|id=|name=)[^>]))*((?:class|id|name)=['"][^'"]*['"]\s*)?)(?:(?:(?:(?!class=|id=|name=)[^>]))*((?:class|id|name)=['"][^'"]*['"]\s*)?)(?:(?:(?:(?!class=|id=|name=)[^>]))*((?:class|id|name)=['"][^'"]*['"]\s*)?)[^>]*>
(see it in action here).