回答編集履歴

3

表現の修正

2019/02/06 05:52

投稿

LouiS0616
LouiS0616

スコア35660

test CHANGED
@@ -188,7 +188,7 @@
188
188
 
189
189
  一度マッチすれば、それ以上追って検索することはありません。
190
190
 
191
- マッチする部分文字列全体を得たいときには、re.findallやre.finditerを使います。
191
+ マッチする全ての部分文字列を得たいときには、re.findallやre.finditerを使います。
192
192
 
193
193
 
194
194
 

2

追記

2019/02/06 05:52

投稿

LouiS0616
LouiS0616

スコア35660

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

追記

2019/02/06 05:46

投稿

LouiS0616
LouiS0616

スコア35660

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の拡張だったと思います。