teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

追記

2016/08/10 12:19

投稿

hirohiro
hirohiro

スコア2068

answer CHANGED
@@ -1,6 +1,8 @@
1
1
  うるう年などdateの持つ複雑さを正規表現でパターン化するのは難しいのではないかと思います。
2
2
  正規表現で取り出した「日付と思しき」文字列をifと[checkdate](http://php.net/manual/ja/function.checkdate.php)などで別途判別するのが簡単かと。
3
3
 
4
+
5
+ ###追記(2016.08.10)
4
6
  > 2555.1000.3999だと単語境界を使わなくても「正しい西暦と月日を入力しよう」とでてくる
5
7
  ```php
6
8
  $seireki = "2550.1000-3999";//変な年、日にちでもマッチしてしまう。

1

追記

2016/08/10 12:18

投稿

hirohiro
hirohiro

スコア2068

answer CHANGED
@@ -1,2 +1,19 @@
1
1
  うるう年などdateの持つ複雑さを正規表現でパターン化するのは難しいのではないかと思います。
2
- 正規表現で取り出した「日付と思しき」文字列をifと[checkdate](http://php.net/manual/ja/function.checkdate.php)などで別途判別するのが簡単かと。
2
+ 正規表現で取り出した「日付と思しき」文字列をifと[checkdate](http://php.net/manual/ja/function.checkdate.php)などで別途判別するのが簡単かと。
3
+
4
+ > 2555.1000.3999だと単語境界を使わなくても「正しい西暦と月日を入力しよう」とでてくる
5
+ ```php
6
+ $seireki = "2550.1000-3999";//変な年、日にちでもマッチしてしまう。
7
+ if(preg_match("/([1-2]\d\d\d)[\/.\-]([0-1]*[0-9])[\/.\-]([0-3]*[0-9])/",$seireki,$data)) {
8
+ echo "<p>".$data[1]."年".$data[2]."月".$data[3]."日</p>";
9
+ } else {
10
+ echo "正しい西暦と月日を入力しよう";
11
+ }
12
+ ```
13
+ [paiza](https://paiza.io/)でこのコードを試してみましたが、出力は「<p>2550年1000月39日</p>」でした。2550.10.399でも「<p>2550年10月39日</p>」です。
14
+ 「*」は直前の文字の0回以上の繰り返しなので、
15
+ 月のところは00009にも117にもマッチしますが、123にはマッチしません。0か1が複数あった後に0-9のどれかが来る塊って意味ですね
16
+ 日の所も、0-3のどれかが複数続いた後、0-9のどれかが1文字やってくる塊って意味です。
17
+
18
+ もしかすると、「/\b([1-2]\d\d\d)[\/.\-]([0-1]{0,1}[0-9])[\/.\-]([0-3]{0,1}[0-9])\b/」これの方が目的に一致しているかも知れませんね。{0,1}は直前の文字が無いか1つだけ存在するって意味です。
19
+ この場合は単語境界を書くことで、12009.01.20や2009.02.299をNGにすることが出来ます。