回答編集履歴
9
a
test
CHANGED
@@ -182,17 +182,7 @@
|
|
182
182
|
|
183
183
|
$str = 'I am Tom. He is Mr. Smith.';
|
184
184
|
|
185
|
-
|
186
|
-
|
187
|
-
$sentences = preg_split(
|
188
|
-
|
189
|
-
|
185
|
+
$sentences = preg_split('/(?:Mr|Mr?s|Dr|Sir|Prof)\.(*SKIP)(*FAIL)|\.\K\s+/', $str);
|
190
|
-
|
191
|
-
$str, -1, PREG_SPLIT_NO_EMPTY
|
192
|
-
|
193
|
-
);
|
194
|
-
|
195
|
-
|
196
186
|
|
197
187
|
var_dump($sentences);
|
198
188
|
|
@@ -200,8 +190,6 @@
|
|
200
190
|
|
201
191
|
/*
|
202
192
|
|
203
|
-
|
204
|
-
|
205
193
|
array(2) {
|
206
194
|
|
207
195
|
[0]=>
|
@@ -214,8 +202,6 @@
|
|
214
202
|
|
215
203
|
}
|
216
204
|
|
217
|
-
|
218
|
-
|
219
205
|
*/
|
220
206
|
|
221
207
|
```
|
8
あ
test
CHANGED
@@ -159,3 +159,67 @@
|
|
159
159
|
|
160
160
|
|
161
161
|
という処理を行っています.
|
162
|
+
|
163
|
+
|
164
|
+
|
165
|
+
----
|
166
|
+
|
167
|
+
|
168
|
+
|
169
|
+
【追記】
|
170
|
+
|
171
|
+
|
172
|
+
|
173
|
+
コメントにも書きましたが,こちらにも最終目的のコードをシンタックスハイライトをつけて書いておきます.
|
174
|
+
|
175
|
+
|
176
|
+
|
177
|
+
```php
|
178
|
+
|
179
|
+
<?php
|
180
|
+
|
181
|
+
|
182
|
+
|
183
|
+
$str = 'I am Tom. He is Mr. Smith.';
|
184
|
+
|
185
|
+
|
186
|
+
|
187
|
+
$sentences = preg_split(
|
188
|
+
|
189
|
+
'/(?:Mr|Mr?s|Dr|Sir|Prof)\.(*SKIP)(*FAIL)|\.\K\s+/',
|
190
|
+
|
191
|
+
$str, -1, PREG_SPLIT_NO_EMPTY
|
192
|
+
|
193
|
+
);
|
194
|
+
|
195
|
+
|
196
|
+
|
197
|
+
var_dump($sentences);
|
198
|
+
|
199
|
+
|
200
|
+
|
201
|
+
/*
|
202
|
+
|
203
|
+
|
204
|
+
|
205
|
+
array(2) {
|
206
|
+
|
207
|
+
[0]=>
|
208
|
+
|
209
|
+
string(9) "I am Tom."
|
210
|
+
|
211
|
+
[1]=>
|
212
|
+
|
213
|
+
string(16) "He is Mr. Smith."
|
214
|
+
|
215
|
+
}
|
216
|
+
|
217
|
+
|
218
|
+
|
219
|
+
*/
|
220
|
+
|
221
|
+
```
|
222
|
+
|
223
|
+
|
224
|
+
|
225
|
+
|
7
a
test
CHANGED
@@ -154,6 +154,8 @@
|
|
154
154
|
|
155
155
|
3. 現在位置を今マッチさせたバイト列のぶんだけ進める.マッチしていなければ1バイト進める.
|
156
156
|
|
157
|
+
4. まだ後ろに1バイト以上あれば1に戻る.無ければ終了する.
|
158
|
+
|
157
159
|
|
158
160
|
|
159
161
|
という処理を行っています.
|
6
a
test
CHANGED
@@ -152,7 +152,7 @@
|
|
152
152
|
|
153
153
|
2. **後ろに「カレー」「ライス」「末尾」のいずれかが来るように**,1バイト以上の可能な限り短いバイト列を探す.マッチしたら置換処理を行う.マッチしなければ3に進む.
|
154
154
|
|
155
|
-
3. 現在位置を今マッチさせたバイト列のぶんだけ進める.
|
155
|
+
3. 現在位置を今マッチさせたバイト列のぶんだけ進める.マッチしていなければ1バイト進める.
|
156
156
|
|
157
157
|
|
158
158
|
|
5
a
test
CHANGED
@@ -152,7 +152,7 @@
|
|
152
152
|
|
153
153
|
2. **後ろに「カレー」「ライス」「末尾」のいずれかが来るように**,1バイト以上の可能な限り短いバイト列を探す.マッチしたら置換処理を行う.マッチしなければ3に進む.
|
154
154
|
|
155
|
-
3. 現在位置を今マッチさせた
|
155
|
+
3. 現在位置を今マッチさせたバイト列のぶんだけ進める.
|
156
156
|
|
157
157
|
|
158
158
|
|
4
a
test
CHANGED
@@ -13,10 +13,6 @@
|
|
13
13
|
```php
|
14
14
|
|
15
15
|
<?php
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
header('Content-Type: text/plain; charset=UTF-8');
|
20
16
|
|
21
17
|
|
22
18
|
|
@@ -37,10 +33,6 @@
|
|
37
33
|
```php
|
38
34
|
|
39
35
|
<?php
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
header('Content-Type: text/plain; charset=UTF-8');
|
44
36
|
|
45
37
|
|
46
38
|
|
@@ -106,7 +98,7 @@
|
|
106
98
|
|
107
99
|
|
108
100
|
|
109
|
-
`strtr` `preg_replace (単一の正規表現で処理)` においては一度置換したところを次回の置換対象から外してくれますが, `str_replace` `preg_replace (複数の正規表現で処理)` においては全く考慮してくれません. 速度面においても,僅かな違いですが,一般的には速い順に
|
101
|
+
**`strtr` `preg_replace (単一の正規表現で処理)` においては一度置換したところを次回の置換対象から外してくれますが, `str_replace` `preg_replace (複数の正規表現で処理)` においては全く考慮してくれません. **速度面においても,僅かな違いですが,一般的には速い順に
|
110
102
|
|
111
103
|
|
112
104
|
|
@@ -124,17 +116,13 @@
|
|
124
116
|
|
125
117
|
|
126
118
|
|
127
|
-
また正規表現の高度なテクニックですが,バックトラッキングコントロールを使うとまさに「あるバイト列以外のバイト列を直接マッチさせることもできます.
|
119
|
+
また正規表現の高度なテクニックですが,バックトラッキングコントロールを使うとまさに**「あるバイト列以外のバイト列」**を直接マッチさせることもできます.
|
128
120
|
|
129
121
|
|
130
122
|
|
131
123
|
```php
|
132
124
|
|
133
125
|
<?php
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
header('Content-Type: text/plain; charset=UTF-8');
|
138
126
|
|
139
127
|
|
140
128
|
|
3
a
test
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
|
4
4
|
|
5
|
-
-[マルチバイト文字を扱う際に気をつけること](http://qiita.com/mpyw/items/a8dba1b80fe68523b8eb)
|
5
|
+
- [マルチバイト文字を扱う際に気をつけること](http://qiita.com/mpyw/items/a8dba1b80fe68523b8eb)
|
6
6
|
|
7
7
|
|
8
8
|
|
2
一応s修飾子を追加
test
CHANGED
@@ -1,4 +1,36 @@
|
|
1
|
-
|
1
|
+
まず前提として,この回答においては文字列ではなく**バイト列**という表記にします.日本語を相手にしても本当に1文字という単位で見てくれるのは`u`修飾子をつけた`preg_*`系の関数,あるいは文字コードをUTF-8として正しく指定した`mb_*`系の関数のみです.残りの関数は全てバイト単位で計算します.
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
-[マルチバイト文字を扱う際に気をつけること](http://qiita.com/mpyw/items/a8dba1b80fe68523b8eb)
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
本題に入ります.既に回答にありますが,**除外したいバイト列を空白に置換して残ったバイト列を得る**というアプローチにて`preg_replace`あるいは`preg_replace_callback`を使って済むのであればそれが一番簡単です.正規表現無しでも簡単に書ける範囲であれば`str_replace`や`strtr`を使うほうがよいでしょう.なお文字コードがUTF-8である場合は,正規表現の文字クラス`[]`を使わない限り,「文字列=バイト列」のように扱っても正しく動作します.このことは上にリンクしたQiitaの記事でも解説しています.
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
```php
|
14
|
+
|
15
|
+
<?php
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
header('Content-Type: text/plain; charset=UTF-8');
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
$str = 'ライスパスタカレーパスタドリア';
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
echo str_replace('パスタ', '', $str), "\n"; // ライスカレードリア
|
28
|
+
|
29
|
+
```
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
但しこれらには,複数の置換を同時に行う際に微妙な違いがあるので注意してください.以下を実行してみるとわかります.
|
2
34
|
|
3
35
|
|
4
36
|
|
@@ -18,6 +50,8 @@
|
|
18
50
|
|
19
51
|
print_r([
|
20
52
|
|
53
|
+
|
54
|
+
|
21
55
|
'str_replace' => str_replace(
|
22
56
|
|
23
57
|
['カレーライス', 'カレー', 'ライス'],
|
@@ -26,7 +60,9 @@
|
|
26
60
|
|
27
61
|
$str
|
28
62
|
|
29
|
-
),
|
63
|
+
), // 【ライス】パスタ【ライス】【【カレー】【ライス】】【カレー】ドリア
|
64
|
+
|
65
|
+
|
30
66
|
|
31
67
|
'strtr' => strtr($str, [
|
32
68
|
|
@@ -36,7 +72,9 @@
|
|
36
72
|
|
37
73
|
'ライス' => '【ライス】',
|
38
74
|
|
39
|
-
]),
|
75
|
+
]), // 【ライス】パスタ【ライス】【カレーライス】【カレー】ドリア
|
76
|
+
|
77
|
+
|
40
78
|
|
41
79
|
'preg_replace (複数の正規表現で処理)' => preg_replace(
|
42
80
|
|
@@ -46,7 +84,9 @@
|
|
46
84
|
|
47
85
|
$str
|
48
86
|
|
49
|
-
),
|
87
|
+
), // 【ライス】パスタ【ライス】【【カレー】【ライス】】【カレー】ドリア
|
88
|
+
|
89
|
+
|
50
90
|
|
51
91
|
'preg_replace (単一の正規表現で処理)' => preg_replace(
|
52
92
|
|
@@ -56,7 +96,9 @@
|
|
56
96
|
|
57
97
|
$str
|
58
98
|
|
59
|
-
),
|
99
|
+
), // 【ライス】パスタ【ライス】【カレーライス】【カレー】ドリア
|
100
|
+
|
101
|
+
|
60
102
|
|
61
103
|
]);
|
62
104
|
|
@@ -64,7 +106,25 @@
|
|
64
106
|
|
65
107
|
|
66
108
|
|
109
|
+
`strtr` `preg_replace (単一の正規表現で処理)` においては一度置換したところを次回の置換対象から外してくれますが, `str_replace` `preg_replace (複数の正規表現で処理)` においては全く考慮してくれません. 速度面においても,僅かな違いですが,一般的には速い順に
|
110
|
+
|
111
|
+
|
112
|
+
|
113
|
+
1. `str_replace`
|
114
|
+
|
115
|
+
2. `strtr` (実はもう1つ使い方があるがこの例のように連想配列で置換する場合)
|
116
|
+
|
117
|
+
3. `preg_replace (単一の正規表現で処理)`
|
118
|
+
|
119
|
+
4. `preg_replace (複数の正規表現で処理)`
|
120
|
+
|
121
|
+
|
122
|
+
|
123
|
+
として差がつくと思うので,書きやすさも考慮して適宜使い分けてください.
|
124
|
+
|
125
|
+
|
126
|
+
|
67
|
-
正規表現の高度なテクニックですが,バックトラッキングコントロールを使うとまさに
|
127
|
+
また正規表現の高度なテクニックですが,バックトラッキングコントロールを使うとまさに「あるバイト列以外のバイト列を直接マッチさせることもできます.
|
68
128
|
|
69
129
|
|
70
130
|
|
@@ -82,18 +142,30 @@
|
|
82
142
|
|
83
143
|
|
84
144
|
|
85
|
-
pr
|
145
|
+
echo preg_replace(
|
86
146
|
|
87
|
-
'
|
147
|
+
'/(?:カレー|ライス)(*SKIP)(*FAIL)|.+?(?=カレー|ライス|\z)/s',
|
88
148
|
|
89
|
-
|
149
|
+
'【$0】',
|
90
150
|
|
91
|
-
|
151
|
+
$str
|
92
152
|
|
93
|
-
|
153
|
+
), "\n"; // ライス【パスタ】ライスカレーライスカレー【ドリア】
|
94
|
-
|
95
|
-
),
|
96
|
-
|
97
|
-
]);
|
98
154
|
|
99
155
|
```
|
156
|
+
|
157
|
+
|
158
|
+
|
159
|
+
上記の例では
|
160
|
+
|
161
|
+
|
162
|
+
|
163
|
+
1. まず現在位置から「カレー」「ライス」いずれかにマッチするバイト列を探す.**マッチしたら何も無かったことにして3に進む.**マッチしなければ2に進む.
|
164
|
+
|
165
|
+
2. **後ろに「カレー」「ライス」「末尾」のいずれかが来るように**,1バイト以上の可能な限り短いバイト列を探す.マッチしたら置換処理を行う.マッチしなければ3に進む.
|
166
|
+
|
167
|
+
3. 現在位置を今マッチさせた文字列のぶんだけ進める.
|
168
|
+
|
169
|
+
|
170
|
+
|
171
|
+
という処理を行っています.
|
1
修正
test
CHANGED
@@ -42,7 +42,7 @@
|
|
42
42
|
|
43
43
|
['/カレーライス/', '/カレー/', '/ライス/'],
|
44
44
|
|
45
|
-
|
45
|
+
'【$0】',
|
46
46
|
|
47
47
|
$str
|
48
48
|
|