This snippet uses the non-greedy matcher, and the "m" option to treat strings as multi-lines, so it may not work with all regex parsers.
/\<!\s*--(.*?)(--\s*\>)/m Examples in Ruby IRB: irb(main):029:0> html = <<-EOL irb(main):030:0" <!-- First Comment -- irb(main):031:0" --> Second Comment <!-- irb(main):032:0" -- Third Comment --> irb(main):033:0" EOL => "<!-- First Comment --\n --> Second Comment <!--\n -- Third Comment -->\n" irb(main):075:0> m = html.match(/\<!\s*--(.*?)(--\s*\>)/m) => #<MatchData:0x15915a4> irb(main):076:0> m[0] => "<!-- First Comment --\n -->" irb(main):077:0> m[1] => " First Comment --\n "