Here is what you regular expression looks like, looking at it through an automaton:

So you're actually correctly matching what you want, but you're also capturing two groups:
"<!ELEMENT note (to,from,body)"
"note"
but it will also match other kind of strings, like:
<!ELEMENT%e
(jmopV|)
<!ELEMENT r()
which are not well formed tags.
So you'd better want to make a more precise regex
, like:
<!ELEMENT\s+\w+\s+\((\w+, ?)*\w+\)>
- here's what the regex matches:
- text
<!ELEMENT
\s+ one or more space
\w+ one or more in word character
\s+ one or more space
\( a real parenthesis
( begin of a group
\w+ on or more in word character
, a comma
? one or zero space (could be * zero or more spaces)
)* end of the group, that group being matched zero or more times
\w+ one or more in word character
- (you may want to add
\s* if you want to match optional spaces before the closing parenthesis)
\) closing parenthesis character
- (you may want to add
\s* if you want to match optional spaces before the end of the tag)
> closing tag character

Then, when you do match(/<!ELEMENT\s+\w+\s+\((\w+, *)*\w+\)>/i), you will still get two groups:
"<!ELEMENT note (to,from,body)>"
"from,"
and you have to get the first group, you just need to get the first element of the returned array:
var match = "<!ELEMENT note (to,from,body)>".match(/<!ELEMENT\s+\w+\s+\((\w+, *)*\w+\)>/i);
if (match !== null)
match = match[0];
and if you want to use the regexp object to do so:
pattern = new RegExp(/<!ELEMENT\s+\w+\s+\((\w+, *)*\w+\)>/i)
match = pattern.exec(text)
if (match !== null)
match = match[0]
that will get you the first group of match (which is the full match).
AFTER EDIT:
you want a regex that works on this set of values:
<!ENTITY Aring "&#197;" >,
<!ENTITY aring "&#229;" >,
<!ENTITY agrave "&#224;" >,
<!ENTITY aacute "&#225;" >,
<!ATTLIST ARTICLE AUTHOR CDATA #REQUIRED>,
<!ATTLIST ARTICLE EDITOR CDATA #IMPLIED>,
<!ATTLIST ARTICLE DATE CDATA #IMPLIED>,
<!ATTLIST ARTICLE EDITION CDATA #IMPLIED>,
<!ELEMENT note (to,from,heading,body)>,
<!ELEMENT to (#PCDATA)>,
<!ELEMENT from (#PCDATA)>,
<!ELEMENT heading (#PCDATA)>,
<!ELEMENT body (#PCDATA)>
so you want a regex that looks like this one:
/<!ELEMENT\s+\w+\s+\((\#?\w+,\s*)*\#?\w+\s*\)\s*>/

look it up here
var match = "<!ELEMENT note (to,from,body)>".match(/<!ELEMENT\s+\w+\s+\((\#?\w+,\s*)*\#?\w+\s*\)\s*>/i);
if (match !== null)
match = match[0];
there it matches only the <!ELEMENT... nodes, not the <!ATTLIST... or <!ENTITY... nodes. For those ones, match will be equal to null. For <!ELEMENT... nodes, they will contain the full string of the matched node.