Skip to content

Commit

Permalink
refactor(string): 検索文字列に統一
Browse files Browse the repository at this point in the history
fix #208
  • Loading branch information
azu committed Jun 30, 2019
1 parent 9df6ccc commit 1f9c9f3
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 32 deletions.
5 changes: 5 additions & 0 deletions prh.yml
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,11 @@ rules:
prh: sparse arrayのこと
- expected: 密な配列
patterns: 密の配列
- expected: 検索文字列
patterns:
- 部分文字列
- 指定文字列
prh: https://github.com/asciidwango/js-primer/issues/208
- expected: テンプレートリテラル
patterns: /Template\s*Literal/i
- expected: テンプレート文字列
Expand Down
68 changes: 36 additions & 32 deletions source/basic/string/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ description: "文字列リテラルを使った文字列の作成から検索や
# 文字列 {#string}

この章ではJavaScriptにおける文字列について学んでいきます。
まずは、文字列の表現方法や文字列の操作方法について見ていきます
まずは、文字列の作成方法や文字列の操作方法について見ていきます
そして、文字列を編集して自由な文字列を作れるようになることがこの章の目的です。

## 文字列を作成する {#create}
Expand Down Expand Up @@ -353,7 +353,7 @@ console.log("ABC" > "ABD"); // => false

このように、JavaScriptの文字列比較はCode Unit同士を比較しています。

## 部分文字列の取得 {#slice}
## 文字列から一部を取得 {#slice}

文字列からその一部を取り出したい場合には、`String#slice`メソッドや`String#substring`メソッドが利用できます。

Expand Down Expand Up @@ -427,19 +427,23 @@ console.log(queryString); // => "?param=1"

### 文字列による検索 {#search-by-string}

文字列による検索は「文字列」から「部分文字列」を検索できます。
Stringメソッドには検索したい状況に応じたものが用意されています。
指定した文字列が文字列中に含まれているかを検索する方法として、Stringメソッドには取得したい結果ごとにメソッドが用意されています。
ここでは、次の3つについて文字列の検索を見ていきます。

- インデックスの取得
- 真偽値の取得
- マッチした文字列の取得

#### インデックスの取得 {#search-index-by-string}

検索した結果「部分文字列」の開始インデックスを取得する`String#indexOf`メソッドと`String#lastIndexOf`メソッドがあります
これは、配列の`Array#indexOf`メソッドと同じで、厳密等価演算子(`===`で一致する文字列のインデックスを取得します
`String#indexOf`メソッドと`String#lastIndexOf`メソッドは、指定した文字列で検索し、その文字列が最初に現れたインデックスを返します
これらは配列の`Array#indexOf`メソッドと同じで、厳密等価演算子(`===`で文字列を検索します
一致する文字列がない場合は`-1`を返します。

- `文字列.indexOf("部分文字列")`: 先頭から検索し、インデックスを返す
- `文字列.lastIndexOf("部分文字列")`: 末尾から検索し、インデックスを返す
- `文字列.indexOf("検索文字列")`: 先頭から検索し、指定された値が最初に現れたインデックスを返す
- `文字列.lastIndexOf("検索文字列")`: 末尾から検索し、指定された値が最初に現れたインデックスを返す

どちらのメソッドも一致する文字列が複数個ある場合でも、指定した部分文字列を一度見つけた時点で検索は終了します
どちらのメソッドも一致する文字列が複数個ある場合でも、指定した検索文字列を一度見つけた時点で検索は終了します

{{book.console}}
```js
Expand All @@ -450,11 +454,11 @@ const str = "にわにはにわにわとりがいる";
console.log(str.indexOf("にわ")); // => 0
// lastIndexOfは末尾から検索しインデックスを返す- "にわにはにわ**にわ**とりがいる"
console.log(str.lastIndexOf("にわ")); // => 6
// 該当する部分文字列が見つからない場合は -1 を返す
// 指定した文字列が見つからない場合は -1 を返す
console.log(str.indexOf("未知のキーワード")); // => -1
```

検索している部分文字列の長さは固定であるため`String#slice`で取得したインデックスと検索した文字列の長さを組み合わせることで検索結果を取得できます。
検索文字列の長さは固定であるため`String#slice`で取得したインデックスと検索した文字列の長さを組み合わせることで検索結果を取得できます。

{{book.console}}
```js
Expand All @@ -470,25 +474,25 @@ if (index !== -1) {

#### 真偽値の取得 {#test-by-string}

「文字列」に「部分文字列」が含まれているかを検索する方法がいくつか用意されています。
「文字列」に「検索文字列」が含まれているかを検索する方法がいくつか用意されています。

- `文字列.startsWith("部分文字列")`: 部分文字列が先頭にあるかの真偽値を返す[ES2015]
- `文字列.endsWith("部分文字列")`: 部分文字列が終端にあるかの真偽値を返す[ES2015]
- `文字列.includes("部分文字列")`: 部分文字列を含むかの真偽値を返す[ES2015]
- `文字列.startsWith("検索文字列")`: 検索文字列が先頭にあるかの真偽値を返す[ES2015]
- `文字列.endsWith("検索文字列")`: 検索文字列が終端にあるかの真偽値を返す[ES2015]
- `文字列.includes("検索文字列")`: 検索文字列を含むかの真偽値を返す[ES2015]

具体的な例をいくつか見てみましょう。

{{book.console}}
```js
// 検索対象となる文字列
const str = "にわにはにわにわとりがいる";
// startsWith - 部分文字列が先頭ならtrue
// startsWith - 検索文字列が先頭ならtrue
console.log(str.startsWith("にわ")); // => true
console.log(str.startsWith("いる")); // => false
// endsWith - 部分文字列が末尾ならtrue
// endsWith - 検索文字列が末尾ならtrue
console.log(str.endsWith("にわ")); // => false
console.log(str.endsWith("いる")); // => true
// includes - 部分文字列が含まれるならtrue
// includes - 検索文字列が含まれるならtrue
console.log(str.includes("にわ")); // => true
console.log(str.includes("いる")); // => true
```
Expand Down Expand Up @@ -533,7 +537,7 @@ const pattern = new RegExp(`\\s{${spaceCount}}`);

`String#indexOf`メソッドの正規表現版ともいえる`String#search`メソッドがあります。

- `String#indexOf(部分文字列)`: 部分文字列にマッチした文字列のインデックスを返す
- `String#indexOf(検索文字列)`: 検索文字列にマッチした文字列のインデックスを返す
- `String#search(/パターン/)`: 正規表現のパターンにマッチした文字列のインデックスを返す

文字列による検索は、検索しマッチした文字列の長さが決まっているため、`indexOf`メソッドでもマッチした文字列が取得できていました。
Expand Down Expand Up @@ -655,13 +659,13 @@ console.log(capture1); // => "6"
```js
// 検索対象となる文字列
const str = "にわにはにわにわとりがいる";
// ^ - 部分文字列が先頭ならtrue
// ^ - 検索文字列が先頭ならtrue
console.log(/^にわ/.test(str)); // => true
console.log(/^いる/.test(str)); // => false
// $ - 部分文字列が末尾ならtrue
// $ - 検索文字列が末尾ならtrue
console.log(/にわ$/.test(str)); // => false
console.log(/いる$/.test(str)); // => true
// 部分文字列が含まれるならtrue
// 検索文字列が含まれるならtrue
console.log(/にわ/.test(str)); // => true
console.log(/いる/.test(str)); // => true
```
Expand Down Expand Up @@ -752,9 +756,9 @@ console.log(newStr); // => "列"
const str = "にわにはにわにわとりがいる";
// 文字列を指定した場合は、最初に一致したものだけが置換される
console.log(str.replace("にわ", "niwa")); // => "niwaにはにわにわとりがいる"
// `g`フラグなしの場合は、最初に一致したものだけが置換される
// `g`フラグなし正規表現の場合は、最初に一致したものだけが置換される
console.log(str.replace(/にわ/, "niwa")); // => "niwaにはにわにわとりがいる"
// `g`フラグで繰り返し置換を行う
// `g`フラグの正規表現の場合は、繰り返し置換を行う
console.log(str.replace(/にわ/g, "niwa")); // => "niwaにはniwaniwaとりがいる"
```

Expand Down Expand Up @@ -801,14 +805,14 @@ console.log(toDateJa("今日は2017-03-01です")); // => "今日は2017年03月
文字列を単純に結合したり置換することで新しい文字列を作れることがわかりました。
一方、構造的な文字列の場合は単純に結合するだけでは意味が異なってしまうことがあります。

ここでの構造的な文字列とは、URL文字列やファイルパス文字列といった構造をもつ文字列です
たとえば、URL文字列は次のような構造を持っており、それぞれの要素に入る文字列の種類などが制限されています。(詳細は「[URL Standard][]」を参照)
ここでの構造的な文字列とは、URL文字列やファイルパス文字列といった文字列中にコンテキストをもっているものを示します
たとえば、URL文字列は次のような構造を持っており、それぞれの要素に入る文字列の種類などが決められています。(詳細は「[URL Standard][]」を参照)

```
"http://example.com/index.html"
^^^^ ^^^^^^^^^^^
| | ^^^^^^^^^^^
scheme host pathname
"https://example.com/index.html"
^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^
| |    |
scheme host pathname
```

これらの文字列を作成する場合は、文字列結合演算子(`+`)で単純に結合するよりも専用の関数を用意する方が安全です。
Expand Down Expand Up @@ -896,14 +900,14 @@ tag(`template ${0} literal ${1}`);
```

しかし、`()`ではなく ``` タグ関数`テンプレート` ``` と記述することで、`タグ関数`が受け取る引数にはタグ付きテンプレート向けの値が渡ってきます。
タグ関数の第一引数にはテンプレートの中身が`${}`で区切られた配列、第二引数以降は`${}`の中に書いた式の評価結果が順番に渡されます。
タグ関数の第一引数にはテンプレートの中身が`${}`で区切られた文字列の配列、第二引数以降は`${}`の中に書いた式の評価結果が順番に渡されます。

{{book.console}}
<!-- doctest:disable -->
```js
// タグ関数は引数の形が決まっていること以外は関数と同じ
function tag(strings, ...values) {
// stringsには文字列部分が${}で区切られて順番に入る
// stringsは文字列のパーツが${}で区切られた配列となる
console.log(strings); // => ["template "," literal ",""]
// valuesには${}の評価値が順番に入る
console.log(values); // => [0, 1]
Expand Down

0 comments on commit 1f9c9f3

Please sign in to comment.