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

回答編集履歴

5

追記

2017/11/27 04:18

投稿

LouiS0616
LouiS0616

スコア35678

answer CHANGED
@@ -57,4 +57,39 @@
57
57
 
58
58
  0. 空だったらダメ
59
59
  0. ドットで区切って四つじゃなかったらダメ
60
- 0. 範囲外だったらダメ
60
+ 0. 範囲外だったらダメ
61
+
62
+ 追記
63
+ ---
64
+ 正規表現を使っていないのに、BAを貰ってしまったので。
65
+ 質問者様のコードは、ちょっと修正すればちゃんと動きます。
66
+ ```Python
67
+ m = re.match('(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])', address)
68
+ ```
69
+
70
+ **問題のあった点**
71
+ - エスケープすべきでない文字をエスケープしていた
72
+ - しかしながらそもそもre.matchなら文頭記号と文末記号は不用
73
+ - 無駄な空白が入っていた
74
+ - 文末の一文字も余計だった(文末記号以降にオプション付ける文法とかありましたっけ...?)
75
+
76
+ ```Python
77
+ import re
78
+ import random
79
+
80
+ def get_random_address():
81
+ return '{}.{}.{}.{}'.format(
82
+ *[random.randrange(255) for _ in range(4)]
83
+ )
84
+
85
+ compiled_pattern = re.compile('(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])')
86
+ for _ in range(10000):
87
+ address = get_random_address()
88
+ if not compiled_pattern.match(address):
89
+ print('False', address)
90
+
91
+ print('True')
92
+ ```
93
+
94
+ 一応上記のゴリゴリテストを通過します。
95
+ 正規表現あんまり得意じゃないので、変なこと書いていたらすみません。

4

追記

2017/11/27 04:18

投稿

LouiS0616
LouiS0616

スコア35678

answer CHANGED
@@ -26,4 +26,35 @@
26
26
  return True
27
27
  except ValueError:
28
28
  return False
29
- ```
29
+ ```
30
+
31
+ 参考までに
32
+ ---
33
+ [CPythonの実装](https://github.com/python/cpython/blob/master/Lib/ipaddress.py#L1116)を見てみると、案外ゴリゴリやってるみたいですね。
34
+ > ```Python
35
+ > @classmethod
36
+ > def _ip_int_from_string(cls, ip_str):
37
+ > """Turn the given IP string into an integer for comparison.
38
+ > Args:
39
+ > ip_str: A string, the IP ip_str.
40
+ > Returns:
41
+ > The IP ip_str as an integer.
42
+ > Raises:
43
+ > AddressValueError: if ip_str isn't a valid IPv4 Address.
44
+ > """
45
+ > if not ip_str:
46
+ > raise AddressValueError('Address cannot be empty')
47
+
48
+ > octets = ip_str.split('.')
49
+ > if len(octets) != 4:
50
+ > raise AddressValueError("Expected 4 octets in %r" % ip_str)
51
+
52
+ > try:
53
+ > return int.from_bytes(map(cls._parse_octet, octets), 'big')
54
+ > except ValueError as exc:
55
+ > raise AddressValueError("%s in %r" % (exc, ip_str)) from None
56
+ > ```
57
+
58
+ 0. 空だったらダメ
59
+ 0. ドットで区切って四つじゃなかったらダメ
60
+ 0. 範囲外だったらダメ

3

注意書き

2017/11/23 08:15

投稿

LouiS0616
LouiS0616

スコア35678

answer CHANGED
@@ -1,3 +1,6 @@
1
+ **註:以下の回答は、正規表現に関するものではありません。**
2
+ **何らかの制約や目標があって正規表現を用いたいなら、あまり参考にはならないと思います。**
3
+
1
4
  [IPアドレスに関する標準ライブラリ](https://docs.python.jp/3/library/ipaddress.html)を利用するのが良いと思います。
2
5
  ```Python
3
6
  >>> import ipaddress

2

追記

2017/11/23 07:46

投稿

LouiS0616
LouiS0616

スコア35678

answer CHANGED
@@ -11,4 +11,16 @@
11
11
  File "C:\ProgramData\Miniconda3\lib\ipaddress.py", line 54, in ip_address
12
12
  address)
13
13
  ValueError: '1.2.3.300' does not appear to be an IPv4 or IPv6 address
14
+ ```
15
+
16
+ こういう関数を作ってもいいかもしれませんね。
17
+ ```Python
18
+ import ipaddress
19
+
20
+ def is_valid_ip(arg):
21
+ try:
22
+ ipaddress.ip_address(arg)
23
+ return True
24
+ except ValueError:
25
+ return False
14
26
  ```

1

追記

2017/11/23 07:44

投稿

LouiS0616
LouiS0616

スコア35678

answer CHANGED
@@ -1,4 +1,4 @@
1
- IPアドレスに関する標準ライブラリを利用するのが良いと思います。
1
+ [IPアドレスに関する標準ライブラリ](https://docs.python.jp/3/library/ipaddress.html)を利用するのが良いと思います。
2
2
  ```Python
3
3
  >>> import ipaddress
4
4
  >>>