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