/<meta\s.*?content="(.*?)"\s+name="description"/si
deals to the case issue. If you don't know the order, you can either go
/<meta\s.*?(content="(.*?)"\s+name="description"|name="description"\s+content="(.*?)")/si
or use an assertion
/<meta(?=[^>]*name="description")\s[^>]*content="([^>]*)"/si
which makes sure that the <meta is followed somewhere by name="description" before the tag closes, before going on to try matching the content attribute. Replacing .? with [>] is both an efficiency saving and also makes sure we really do stop at the end of the tag ([>]* means "match zero or more non-> characters") if for some reason there is no content attribute (otherwise we'll end up trying possible match after possible match all the way to the end of the page before giving up).