回答編集履歴
3
表現の修正
test
CHANGED
@@ -188,7 +188,7 @@
|
|
188
188
|
|
189
189
|
一度マッチすれば、それ以上追って検索することはありません。
|
190
190
|
|
191
|
-
マッチする部分文字列
|
191
|
+
マッチする全ての部分文字列を得たいときには、re.findallやre.finditerを使います。
|
192
192
|
|
193
193
|
|
194
194
|
|
2
追記
test
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
()の意味について
|
2
|
+
|
3
|
+
---
|
4
|
+
|
1
5
|
> 色々調べてグループ化の()と思うのですが、グループ化しなくても.*だけで任意の文字列を表しているので、()は必要ないのではと思いました。
|
2
6
|
|
3
7
|
|
@@ -130,10 +134,102 @@
|
|
130
134
|
|
131
135
|
|
132
136
|
|
137
|
+
re.searchの挙動
|
138
|
+
|
139
|
+
---
|
140
|
+
|
141
|
+
> しかし、(2)だと次はsayの後の"と、Yesの前の"の文字列", "の中身が表示されるのかと思ったらエラーが出てしまいました。
|
142
|
+
|
143
|
+
|
144
|
+
|
145
|
+
誤解されている点がいくつかあります。
|
146
|
+
|
147
|
+
|
148
|
+
|
149
|
+
- **正規表現は広い範囲にマッチした後、部分にマッチすることはありません。**
|
150
|
+
|
151
|
+
もしそんな挙動だと、.+ のマッチ件数がとんでもないことになります。
|
152
|
+
|
153
|
+
|
154
|
+
|
155
|
+
```Python
|
156
|
+
|
157
|
+
>>> m = re.search(r'"(.+?)", "(.+?)"', content)
|
158
|
+
|
159
|
+
>>> m.groups()
|
160
|
+
|
161
|
+
('You say', 'Yes, I am.')
|
162
|
+
|
163
|
+
>>>
|
164
|
+
|
165
|
+
>>> m.group(0)
|
166
|
+
|
167
|
+
'"You say", "Yes, I am."'
|
168
|
+
|
169
|
+
>>> m.group(1)
|
170
|
+
|
171
|
+
'You say'
|
172
|
+
|
173
|
+
>>> m.group(2)
|
174
|
+
|
175
|
+
'Yes, I am.'
|
176
|
+
|
177
|
+
```
|
178
|
+
|
179
|
+
|
180
|
+
|
181
|
+
結局広い範囲に一回だけマッチしているに過ぎません。
|
182
|
+
|
183
|
+
groupはその際にキャプチャした部分マッチを取り出しているだけです。
|
184
|
+
|
185
|
+
|
186
|
+
|
187
|
+
- **re.searchはマッチした際に検索を打ち切ります。**
|
188
|
+
|
189
|
+
一度マッチすれば、それ以上追って検索することはありません。
|
190
|
+
|
191
|
+
マッチする部分文字列全体を得たいときには、re.findallやre.finditerを使います。
|
192
|
+
|
193
|
+
|
194
|
+
|
195
|
+
```Python
|
196
|
+
|
197
|
+
>>> re.findall(r'"(.+?)"', content)
|
198
|
+
|
199
|
+
['You say', 'Yes, I am.']
|
200
|
+
|
201
|
+
```
|
202
|
+
|
203
|
+
|
204
|
+
|
205
|
+
ぶっちゃけこっちの方がご提示の例には即していると思います。
|
206
|
+
|
207
|
+
|
208
|
+
|
133
209
|
発展
|
134
210
|
|
135
211
|
---
|
136
212
|
|
213
|
+
さりげなく (.+?) という正規表現を何回か使っていますが、これは**最左最短マッチ**です。
|
214
|
+
|
215
|
+
単に**最短マッチ**と呼ぶこともありますし、**非貪欲マッチ**と呼ばれることもあります。
|
216
|
+
|
217
|
+
|
218
|
+
|
219
|
+
これについては、Pythonのリファレンスに詳しいです。
|
220
|
+
|
221
|
+
> ######*?, +?, ??
|
222
|
+
|
223
|
+
'*' 、 '+' 、 '?' といった修飾子は、すべて 貪欲 (greedy) マッチ、すなわちできるだけ多くのテキストにマッチするようになっています。時にはこの動作が望ましくない場合もあります。例えば正規表現 <.*> を '<a> b <c>' にマッチさせると、 '<a>' だけにマッチするのではなく全文字列にマッチしてしまいます。 ? を修飾子の後に追加すると、 非貪欲 (non-greedy) あるいは 最小一致 (minimal) のマッチになり、できるだけ 少ない 文字数のマッチになります。例えば正規表現 <.*?> を使うと '<a>' だけにマッチします。
|
224
|
+
|
225
|
+
|
226
|
+
|
227
|
+
引用元: [Python 標準ライブラリ » 正規表現のシンタックス](https://docs.python.jp/3/library/re.html#regular-expression-syntax)
|
228
|
+
|
229
|
+
|
230
|
+
|
231
|
+
---
|
232
|
+
|
137
233
|
**『グループ化はしたいけどキャプチャはしたくない』**というときも往々にしてありますが、
|
138
234
|
|
139
235
|
そのようなときは (?:正規表現) を使うことができます。
|
1
追記
test
CHANGED
@@ -44,9 +44,9 @@
|
|
44
44
|
|
45
45
|
確かにマッチできていますね。
|
46
46
|
|
47
|
-
またこのようなケースでは、名前部分だけ取り出したいという要求が生じがちです。
|
48
47
|
|
49
48
|
|
49
|
+
しかしこのようなケースでは、名前部分だけ取り出したいという要求が生じがちです。
|
50
50
|
|
51
51
|
キャプチャを用いれば、文字列を部分的に切り出すことが簡単にできます。
|
52
52
|
|
@@ -66,7 +66,11 @@
|
|
66
66
|
|
67
67
|
|
68
68
|
|
69
|
+
---
|
70
|
+
|
69
71
|
その他にも、後方参照に用いることもあります。
|
72
|
+
|
73
|
+
以下の例は**『同じワードを二回だけ繰り返している文字列』**にマッチします。
|
70
74
|
|
71
75
|
```Python
|
72
76
|
|
@@ -96,6 +100,70 @@
|
|
96
100
|
|
97
101
|
|
98
102
|
|
103
|
+
以下の例は、置換にキャプチャを利用しているものです。
|
104
|
+
|
105
|
+
```Python
|
106
|
+
|
107
|
+
>>> src = 'Check, 123'
|
108
|
+
|
109
|
+
>>>
|
110
|
+
|
111
|
+
>>> re.sub(r'(\d+)', r'\1', src)
|
112
|
+
|
113
|
+
'Check, 123'
|
114
|
+
|
115
|
+
>>> re.sub(r'(\d+)', r'\1\1', src)
|
116
|
+
|
117
|
+
'Check, 123123'
|
118
|
+
|
119
|
+
>>> re.sub(r'(\d+)', r'\1\1\1', src)
|
120
|
+
|
121
|
+
'Check, 123123123'
|
122
|
+
|
123
|
+
```
|
124
|
+
|
125
|
+
|
126
|
+
|
99
127
|
---
|
100
128
|
|
101
129
|
**註:** 本来なら正規表現で解決するタスクでは無いですが、あくまで簡単な例として。
|
130
|
+
|
131
|
+
|
132
|
+
|
133
|
+
発展
|
134
|
+
|
135
|
+
---
|
136
|
+
|
137
|
+
**『グループ化はしたいけどキャプチャはしたくない』**というときも往々にしてありますが、
|
138
|
+
|
139
|
+
そのようなときは (?:正規表現) を使うことができます。
|
140
|
+
|
141
|
+
```Python
|
142
|
+
|
143
|
+
>>> m = re.match(r'(\d{2})+', '343434')
|
144
|
+
|
145
|
+
>>> print(m)
|
146
|
+
|
147
|
+
<_sre.SRE_Match object; span=(0, 6), match='343434'>
|
148
|
+
|
149
|
+
>>> print(m.groups())
|
150
|
+
|
151
|
+
('34',)
|
152
|
+
|
153
|
+
>>>
|
154
|
+
|
155
|
+
>>> m = re.match(r'(?:\d{2})+', '343434')
|
156
|
+
|
157
|
+
>>> print(m)
|
158
|
+
|
159
|
+
<_sre.SRE_Match object; span=(0, 6), match='343434'>
|
160
|
+
|
161
|
+
>>> print(m.groups())
|
162
|
+
|
163
|
+
()
|
164
|
+
|
165
|
+
```
|
166
|
+
|
167
|
+
|
168
|
+
|
169
|
+
これはPythonの正規表現拡張です。元はPerlの拡張だったと思います。
|