文字列から日付を抜き出す正規表現について

日付は様々な表記方法、月により変わる日数(28日~31日)、閏年などがあり複雑である。
そのため、正規表現だけで完全な日付を抜き出すとなると、かなり冗長で複雑になる。
よって正規表現の日付に関してはある程度の妥協が必要になってくる。

サンプル1

シンプルな正規表現。広い範囲の日付書式を取得できる。しかし、99月99日なんていうのも取れてしまう。
/([0-9]{4})(\/|-|年)([0-9]{1,2})(\/|-|月)([0-9]{1,2})/



出力
いろは2016-6-6ネコ → 2016-6-6
いろは2016-06-06タヌキ → 2016-06-06
いろは2016-12-31ロバ → 2016-12-31
いろは9999-99-99ブタ → 9999-99-99
いろは2016/6/6イヌ → 2016/6/6
いろは2016年6月6日ヤギ → 2016年6月6
いろは2016-6カニ → 一致なし
いろは2016カニ → 一致なし
いろは → 一致なし


サンプル2

サンプル1より少し厳密に日付を取得できるが、6月31日(6月は30日まで)など存在しない日付の値まで取得できてしまう。
どうせ完全な日付が取得できないのであれば、サンプル1で採用し、バリデーション処理を自前で書いたほうが効率がよいかもしれない。
/([1-9][0-9]{3})\/|-|年([1-9]{1}|1[0-2]{1})\/|-|月([1-9]{1}|[1-2]{1}[0-9]{1}|3[0-1]{1})/



出力
いろは2016-6-6ネコ → 2016-6-6
いろは2016-6-31 → 2016-6-31
いろは2016-06-06タヌキ → 2016-06-06
いろは2016-12-31ロバ → 2016-12-31
いろは9999-99-99ブタ → 一致なし
いろは2016/6/6イヌ → 2016/6/6
いろは2016年6月6日ヤギ → 2016年6月6
いろは2016-6カニ → 一致なし
いろは2016カニ → 一致なし
いろは → 一致なし