$switchable = qr/foo|quux|glarf|boojum/; $name = qr/[^\s<>=]+/; # broader than the XML Spec, but that's OK $attValue = qr/(?:'[^'<>]*'|"[^"<>]*")/; $attribute = qr/(?:\s+(?>$name)\s*=\s*(?>$attValue))/; s/ ^ < ($switchable) ($attribute*?) # get the value of the type attribute (\s+) type (\s*=\s*) (['"]) # either quote allowable # but then the other quote char # or just about anything else # is allowed inside ... # minimal match for efficiency ((?(?<=')[^']*?|[^"]*?)) \5 # matching close quote ($attribute*?) (\s*) > (.*) # what's between tags, even newline <\/ \1 # matching end tag (\s*) > $ /<$6$2$3metaType$4$5$1$5$7$8>$9<\/$6$10>/sox