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

回答編集履歴

5

修正

2021/09/05 06:56

投稿

Zuishin
Zuishin

スコア28675

answer CHANGED
@@ -3,14 +3,14 @@
3
3
  ```js
4
4
  const src = "特に山梨県の梨はみずみずしくて美味い";
5
5
 
6
- const dst = src.replaceAll(/山梨県|梨/g, a => a === "梨" ? "りんご" : a);
6
+ const dst = src.replaceAll(/山梨県|梨/gu, a => a === "梨" ? "りんご" : a);
7
7
  console.log(dst);
8
8
  ```
9
9
 
10
10
  例えば「山梨県」の他に「二十世紀梨」を対象にするのであれば次のように書き換えます。
11
11
 
12
12
  ```js
13
- const dst = src.replaceAll(/山梨県|二十世紀梨|梨/g, a => a === "梨" ? "りんご" : a);
13
+ const dst = src.replaceAll(/山梨県|二十世紀梨|梨/gu, a => a === "梨" ? "りんご" : a);
14
14
  ```
15
15
 
16
16
  以上を関数化すると次のようになります。
@@ -22,10 +22,18 @@
22
22
 
23
23
  const f = (src, target, ignore, replacement) => {
24
24
  const searchValue = ignore.concat(target).map(escapeRegularExpression).join("|");
25
- const regExp = new RegExp(searchValue, "g");
25
+ const regExp = new RegExp(searchValue, "gu");
26
26
  return src.replace(regExp, a => a === target ? replacement : a);
27
27
  };
28
28
 
29
29
  const dst = f("特に山梨県の梨はみずみずしくて美味い", "梨", ["山梨県"], "りんご");
30
30
  console.log(dst);
31
+ ```
32
+
33
+ target や ignore にメタ文字が含まれておらず、無視する単語が一つということがどちらも保証されているなら、次のように簡単に書いてもいいでしょう。
34
+
35
+ ```js
36
+ const f = (src, target, ignore, replacement) => {
37
+ return src.replace(new RegExp(`${ignore}|${target}`, "gu"), a => a === target ? replacement : a);
38
+ };
31
39
  ```

4

リファクタリング

2021/09/05 06:56

投稿

Zuishin
Zuishin

スコア28675

answer CHANGED
@@ -21,7 +21,7 @@
21
21
  };
22
22
 
23
23
  const f = (src, target, ignore, replacement) => {
24
- const searchValue = ignore.concat(target).map(a => escapeRegularExpression(a)).join("|");
24
+ const searchValue = ignore.concat(target).map(escapeRegularExpression).join("|");
25
25
  const regExp = new RegExp(searchValue, "g");
26
26
  return src.replace(regExp, a => a === target ? replacement : a);
27
27
  };

3

リファクタリング

2021/09/05 04:49

投稿

Zuishin
Zuishin

スコア28675

answer CHANGED
@@ -21,8 +21,7 @@
21
21
  };
22
22
 
23
23
  const f = (src, target, ignore, replacement) => {
24
- const targetValue = escapeRegularExpression(target);
25
- const searchValue = ignore.reduce((previousValue, currentValue) => `${escapeRegularExpression(currentValue)}|${previousValue}`, targetValue);
24
+ const searchValue = ignore.concat(target).map(a => escapeRegularExpression(a)).join("|");
26
25
  const regExp = new RegExp(searchValue, "g");
27
26
  return src.replace(regExp, a => a === target ? replacement : a);
28
27
  };

2

修正

2021/09/05 04:46

投稿

Zuishin
Zuishin

スコア28675

answer CHANGED
@@ -24,7 +24,7 @@
24
24
  const targetValue = escapeRegularExpression(target);
25
25
  const searchValue = ignore.reduce((previousValue, currentValue) => `${escapeRegularExpression(currentValue)}|${previousValue}`, targetValue);
26
26
  const regExp = new RegExp(searchValue, "g");
27
- return src.replace(regExp, a => a === targetValue ? replacement : a);
27
+ return src.replace(regExp, a => a === target ? replacement : a);
28
28
  };
29
29
 
30
30
  const dst = f("特に山梨県の梨はみずみずしくて美味い", "梨", ["山梨県"], "りんご");

1

追記

2021/09/05 04:16

投稿

Zuishin
Zuishin

スコア28675

answer CHANGED
@@ -11,4 +11,22 @@
11
11
 
12
12
  ```js
13
13
  const dst = src.replaceAll(/山梨県|二十世紀梨|梨/g, a => a === "梨" ? "りんご" : a);
14
+ ```
15
+
16
+ 以上を関数化すると次のようになります。
17
+
18
+ ```js
19
+ const escapeRegularExpression = re => {
20
+ return re.replace(/[\^$*+?.(){[|]/g, a => `\${a}`);
21
+ };
22
+
23
+ const f = (src, target, ignore, replacement) => {
24
+ const targetValue = escapeRegularExpression(target);
25
+ const searchValue = ignore.reduce((previousValue, currentValue) => `${escapeRegularExpression(currentValue)}|${previousValue}`, targetValue);
26
+ const regExp = new RegExp(searchValue, "g");
27
+ return src.replace(regExp, a => a === targetValue ? replacement : a);
28
+ };
29
+
30
+ const dst = f("特に山梨県の梨はみずみずしくて美味い", "梨", ["山梨県"], "りんご");
31
+ console.log(dst);
14
32
  ```