回答編集履歴

5

追記

2017/11/27 04:18

投稿

LouiS0616
LouiS0616

スコア35660

test CHANGED
@@ -117,3 +117,73 @@
117
117
  0. ドットで区切って四つじゃなかったらダメ
118
118
 
119
119
  0. 範囲外だったらダメ
120
+
121
+
122
+
123
+ 追記
124
+
125
+ ---
126
+
127
+ 正規表現を使っていないのに、BAを貰ってしまったので。
128
+
129
+ 質問者様のコードは、ちょっと修正すればちゃんと動きます。
130
+
131
+ ```Python
132
+
133
+ 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)
134
+
135
+ ```
136
+
137
+
138
+
139
+ **問題のあった点**
140
+
141
+ - エスケープすべきでない文字をエスケープしていた
142
+
143
+ - しかしながらそもそもre.matchなら文頭記号と文末記号は不用
144
+
145
+ - 無駄な空白が入っていた
146
+
147
+ - 文末の一文字も余計だった(文末記号以降にオプション付ける文法とかありましたっけ...?)
148
+
149
+
150
+
151
+ ```Python
152
+
153
+ import re
154
+
155
+ import random
156
+
157
+
158
+
159
+ def get_random_address():
160
+
161
+ return '{}.{}.{}.{}'.format(
162
+
163
+ *[random.randrange(255) for _ in range(4)]
164
+
165
+ )
166
+
167
+
168
+
169
+ 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])')
170
+
171
+ for _ in range(10000):
172
+
173
+ address = get_random_address()
174
+
175
+ if not compiled_pattern.match(address):
176
+
177
+ print('False', address)
178
+
179
+
180
+
181
+ print('True')
182
+
183
+ ```
184
+
185
+
186
+
187
+ 一応上記のゴリゴリテストを通過します。
188
+
189
+ 正規表現あんまり得意じゃないので、変なこと書いていたらすみません。

4

追記

2017/11/27 04:18

投稿

LouiS0616
LouiS0616

スコア35660

test CHANGED
@@ -55,3 +55,65 @@
55
55
  return False
56
56
 
57
57
  ```
58
+
59
+
60
+
61
+ 参考までに
62
+
63
+ ---
64
+
65
+ [CPythonの実装](https://github.com/python/cpython/blob/master/Lib/ipaddress.py#L1116)を見てみると、案外ゴリゴリやってるみたいですね。
66
+
67
+ > ```Python
68
+
69
+ > @classmethod
70
+
71
+ > def _ip_int_from_string(cls, ip_str):
72
+
73
+ > """Turn the given IP string into an integer for comparison.
74
+
75
+ > Args:
76
+
77
+ > ip_str: A string, the IP ip_str.
78
+
79
+ > Returns:
80
+
81
+ > The IP ip_str as an integer.
82
+
83
+ > Raises:
84
+
85
+ > AddressValueError: if ip_str isn't a valid IPv4 Address.
86
+
87
+ > """
88
+
89
+ > if not ip_str:
90
+
91
+ > raise AddressValueError('Address cannot be empty')
92
+
93
+
94
+
95
+ > octets = ip_str.split('.')
96
+
97
+ > if len(octets) != 4:
98
+
99
+ > raise AddressValueError("Expected 4 octets in %r" % ip_str)
100
+
101
+
102
+
103
+ > try:
104
+
105
+ > return int.from_bytes(map(cls._parse_octet, octets), 'big')
106
+
107
+ > except ValueError as exc:
108
+
109
+ > raise AddressValueError("%s in %r" % (exc, ip_str)) from None
110
+
111
+ > ```
112
+
113
+
114
+
115
+ 0. 空だったらダメ
116
+
117
+ 0. ドットで区切って四つじゃなかったらダメ
118
+
119
+ 0. 範囲外だったらダメ

3

注意書き

2017/11/23 08:15

投稿

LouiS0616
LouiS0616

スコア35660

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

2

追記

2017/11/23 07:46

投稿

LouiS0616
LouiS0616

スコア35660

test CHANGED
@@ -25,3 +25,27 @@
25
25
  ValueError: '1.2.3.300' does not appear to be an IPv4 or IPv6 address
26
26
 
27
27
  ```
28
+
29
+
30
+
31
+ こういう関数を作ってもいいかもしれませんね。
32
+
33
+ ```Python
34
+
35
+ import ipaddress
36
+
37
+
38
+
39
+ def is_valid_ip(arg):
40
+
41
+ try:
42
+
43
+ ipaddress.ip_address(arg)
44
+
45
+ return True
46
+
47
+ except ValueError:
48
+
49
+ return False
50
+
51
+ ```

1

追記

2017/11/23 07:44

投稿

LouiS0616
LouiS0616

スコア35660

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