.net column
.NET開発者のためのブログメディア

JavaScriptで文字列を比較・検索するには?正規表現を使った方法も紹介

 
JavaScriptで文字列を比較・検索するには?正規表現を使った方法も紹介

SE
JavaScriptで文字列検索するには、どうしたらいいのでしょうか?

PM
基本から高度な検索方法までご紹介していきましょう。

JavaScriptの文字列検索とは?


特定の単語がテキスト中に存在するか調べる「検索」という行為は、日常的にもよく行うことです。例えば、専門書を読む際には巻末の索引から知りたい知識に関連する単語を探します。もっと一般的には、宝くじの当せん番号を自分の手持ちの番号と見比べて一致しているか確認する行為も検索に該当します。

コンピュータが扱うデータ化されたテキスト内から目的の一部分を探す、というのは主にコンピュータープログラムが行うもので、HTMLというテキストを扱うことに長けているJavaScriptにも文字列を検索する機能が備わっています。

この記事では、JavaScriptの文字列の検索機能について説明します。

JavaScriptの文字列比較とは?

対象のもの同士を比べてその相違点を見定めるような行為は日常的に行います。例えば、スーパーで同じキャベツを買うときにキャベツ売り場から新鮮に見えるキャベツを他のキャベツと「比較」して購入します。また、テスト結果で表示される偏差値も他の受験者との「比較」するための数値です。

今回説明する文字列比較とは「文字列」と「文字列」の比較を行うことを表します。文字列比較ですが文字の羅列をある部分まで切り取って文字列と認識して比較するので、ある意味先述した文字列検索の機能を一部使うとも言えるでしょう。

以降では、JavaScriptにおける文字列比較や文字列検索の具体的な方法や正規表現と呼ばれている方法について記述していきます。

JavaScriptの文字列の比較方法3つ

JavaScriptの文字列比較では主に3つの手段を使います。「等価演算子」と「厳密等価演算子」と「比較演算子」です。以下では、それぞれについて詳しく説明していきます。

1:等価演算子を使う

等価演算子とは、「==」を使って文字列を比較することです。次の例を見てください。

文字列「apple」と文字列「banana」を比較していることがわかります。実行結果は

となり、文字列を正しく比較できていることが分かります。

2:厳密等価演算子を使う

厳密比較演算子とは「===」のことを指します。次の例を見てください。

ここではString型の文字列appleを定義しています。先ほどの比較演算子と並べて実行すると

この実行結果は

となります。

ここでわかるように「==」と「===」の比較結果では実行結果に差が出る可能性があります。
等価演算子(==)では値だけを比較して変数の型までは比較しないのに対し、厳密比較演算子は値と型の両方を比較する、といった性質の違いによるものです。

3:比較演算子を使う

JavaScriptで利用できる比較演算子とその比較演算子による文字列の判定の方法を以下の表にまとめました。

比較演算子 判定方法
> 左辺が右辺よりも大きい場合はtrue
>= 左辺が右辺よりも大きいか等しい場合はtrue
< 左辺が右辺よりも小さい場合はtrue
<= 左辺が右辺よりも小さいか等しい場合はtrue
=== (==) 左辺と右辺が等しい場合はtrue
!== (!=) 左辺と右辺が等しくない場合はtrue

例を見てみましょう。文字列「あいうえお」と「あいうええ」を比較してみましょう。実行結果は

出力結果は

となります。

ここで上の表にある文字列の大小とはなんでしょうか。これは辞書の順番を考えると簡単にわかります。辞書順を考えると文字列「あいうえお」は「あいうええ」より後に出てきます。そのため、「あいうえお」は「あいうええ」より大きいと考えます。

これは文字列が英語であっても、もちろん数字であっても同じです。文字の差分を考えて辞書順に大小を決めると考えればわかりやすいです。

JavaScriptの文字列の検索方法4つ


いままではJavaScriptにおける簡単な文字列比較の具体的な方法について述べてきました。ここからはJavaScriptの文字列の検索方法について具体的な方法を4つ例をあげつつ紹介していきます。

1:String.prototype.startsWith()

String.prototype.startsWith()メソッドは文字列が指定された文字列から始まっているかをテストします。指定された文字列から始まっていた場合は結果がtrueとなり、始まっていない場合はfalseになります。


上記の例のように、URL文字列などで先頭に特定の文字列が存在するのかを判定するために利用できます。

2:String.prototype.endsWith()

String.prototype.endsWith()メソッドは、文字列が指定された文字列で終わっているかをテストします。指定された文字列で終わっていた場合は結果がtrueとなり、そうでない場合はfalseとなります。


イメージしやすいように宝くじの下4桁の当せん番号を例に示しましたが、他にもテキストデータの終端記号のチェックなどに利用できます。

3:String.prototype.includes()

String.prototype.includes()メソッドは指定された文字列が含まれているかをテストします。先頭や末尾といった箇所に関わらず、検索対象の文字列のどこかに指定の文字列があれば結果はtrueになり、どこにも指定の文字列が無ければfalseになります。

4:indexOf()とlastIndexOf()

ここまでご紹介したメソッドは、どれも結果を真偽値で返すものでした。includes()メソッドは特定の文字列が含まれていることが判定できますが、文字列中のどこに含まれているのかまではわかりません。

指定した文字列が出現する位置を調べたい場合は、String.prototype.indexOf()メソッドかString.prototype.lastIndexOf()メソッドを使います。

indexOf()は指定した文字列が最初に出現する位置を返します。


対して、lastIndexOf()は指定した文字列が最後に出現する位置を返します。


文字列の位置は0から始まります。上記の2つの例では、indexOf()は最初の”赤巻紙”の部分の”巻紙”が検索され、それが文字列中の2文字目から始まっているので位置は1となります。
lastIndexOf()では、最後の”黄巻紙”の”巻紙”が検索され、8文字目の位置7が返されます。

もし指定した文字列が見つからなかった場合には、どちらのメソッドも-1を返します。

JavaScriptの正規表現を利用した文字列の比較・検索方法

ここからはJavaScriptの正規表現を利用した文字列の比較や検索方法について記述していきます。まず見出しにもあるJavaScriptの「正規表現」とは何かを説明します。

Stringオブジェクトが提供しているinclude()やindexOf()などのメソッドは、いずれも引数に文字列を指定し、指定した文字列と完全一致の部分があるか、という判定を行うことはできました。

しかし、単語には”卵”や”玉子”などのように複数の表記をするものがあり、それらすべてを検索したい場合もあります。また、電話番号のように形式が決まっていて、その形式に一致する部分を判断したい場合もあるでしょう。

そのような場合には、検索対象の文字列を「パターン」としてまとめて、そのパターンに合致するかどうかを判定します。文字列のパターンを表現する記法に正規表現という記述方法があり、JavaScriptにも正規表現による文字列検索機能が備わっています。

正規表現にはとても複雑なパターンも表現できるほどの機能があり、それらをすべて網羅し解説するためには、書籍にまとめるほどの情報量が必要です。ここでは、JavaScriptにおける正規表現の便利な機能と、簡単なパターンの説明をすることにとどめます。

パターンマッチによる判定

例えば、利用者からのコメントを受け取り、表示するWebサービスを作成していることにします。その場合に電話番号などの個人情報が表示されるのは問題があるため、電話番号が含まれているか事前に検出したいとします。

そのようなパターンを検出するのには、RegExp.prototype.test()メソッドが利用できます。

ここでは”123-456-7890″のように「数字3桁-数字3桁-数字4桁」のものを電話番号である、と判定することにします。

JavaScriptの正規表現は/パターン/というように、スラッシュ記号/でパターンを表現する文字列を囲みます。正規表現を使うと、先ほどの電話番号のパターンを検索する処理は以下のようになります。


変数patternに正規表現を代入しています。正規表現では、\dは0から9の数字1文字を表します。{3}は直前の表現の3回の繰り返しを表します。ハイフン記号-は上記の例ではそのままのハイフン1文字、という意味です。
つまり、patternに代入された/\d{3}-\d{3}-\d{4}/という正規表現は「数字3回-数字3回-数字4回」という意味になります。

スラッシュ記号/で囲まれた部分はRegExpオブジェクトとなり、RegExpオブジェクトが持つメソッドが利用できます。上記の例ではRegExpオブジェクトのtest()メソッドにcommentを渡して実行しています。

test()メソッドは引数に渡された文字列の中に、パターンに一致する部分があるかどうかを判定します。一致する部分がある場合はtrueが返され、一致しない場合にはfalseが返されます。

このように、正規表現を使用することで文字列の中からパターンに一致する部分を検索できます。

マッチした部分を取得する

文字列の中に特定のパターンが出現するかどうかをRegExp.prototype.test()メソッドで判定できました。続いてはただ判定するだけではなく、パターンに一致する部分を取り出して、何かしらの処理ができるようにしたいと思います。

パターンに一致する部分を取得するには、String.prototype.matchAll()メソッドが利用できます。

文章からカタカナの単語を抜き出す処理を考えてみます。JavaScriptの正規表現は、文字をUnicodeのコード値に基づいて検索することが可能で、カタカナはUnicode上で範囲が決まっています。つまりUnicodeの特定の範囲にある文字の連続からなる文字列をパターンで表現すればよいということになります。


正規表現のパターンは/[\u30a1-\u30f4\u30fc]+/gです。正規表現中の角括弧[]で囲まれた部分には、一致させたい文字の候補を列挙できます。カタカナ1文字を一致させたいので、[アイウエオ…]というようにカタカナをすべて書くこともできますが、それではプログラムが少々長くなってしまいます。

そういった場合、候補の文字が文字コード上で連続しているのであればハイフン-で繋げて間を省略できます。そこでUnicodeのカタカナの範囲で小文字の「ァ」から「ヴ」に該当するコード値の範囲を\u30a1-\u30f4と表現しています。

続いての\u30fcは長音を表す「ー」です。Unicode上では「ヴ」から「-」の間に「ヷ」などのあまり使わない文字があるので、このケースではカタカナであると見なさずに除外しています。

例ではUnicode値を使って連続したコード範囲であることを強調した書き方にしていますが、コードの読みやすさを重視する場合は[ァ-ヴー]と書くこともできます。

角括弧の後のプラス記号+は、直前の表現の1回以上の繰り返しを意味します。角括弧内はカタカナとみなす文字1文字を表しますので、+をつけることで「カタカナ1文字以上からなる文字列」という表現になります。

正規表現の最後にgという文字がありますが、これはフラグというもので正規表現全体の挙動に影響を与える設定値のようなものです。フラグには他にも英語の大文字小文字の違いを無視するような設定をするものなどがあります。

フラグgは主に検索対象全体をチェックする場合に指定します。この後で使用しているmatchAll()メソッドを利用するためにはgフラグを指定する必要があります。

実際の検索処理にはString.prototype.matchAll()メソッドを使用しています。matchAll()は、引数に正規表現を受け取り、表現に一致するすべての部分文字列を取得できるオブジェクトを返します。

注意したいのが、戻り値は結果そのものではなく「結果を取得できるオブジェクト」ということです。戻り値はイテレーターという一致した文字列を順番に取得できる機能をもっているので、for…of文でループさせて検索結果を取得しています。

イテレーターから取得できる検索結果は配列になっており、その先頭に一致した文字列が格納されています。上記の例ではresult[0]というように参照して結果を表示しています。

JavaScriptの正規表現で文字列を扱う際の注意点

JavaScriptの正規表現で文字列を扱う際は記述ミスに注意しましょう。

正規表現は使いこなすことができれば非常に強力で便利です。複雑なパターンにも適用できますが、その分難しく間違いが起こりやすい記述方法です。

JavaScriptにおいてパターンの記述ミスによって検索漏れが発生しないように、まずは検索処理をindexOf()などの簡単な処理の組み合わせで実現できないか考え、それから正規表現の利用を検討してみてください。

SE
JavaScriptの文字列検索は、記述ミスに気を付けるべきですね。

PM
そうですね。検索漏れにつながってしまうので慎重に行いましょう!

JavaScriptで文字列を比較・検索してみよう

ここまでjavaScriptでの文字列の比較・検索の方法を紹介しました。以上の方法をマスターすれば、JavaScriptでの文字列の比較・検索は問題なくできます。

しかし、実際にプログラムを書いていくと文字列の比較や検索はただの手段にすぎません。コードを書いているときに文字列比較や検索を含むコードを書くことは多々あります。

例えば、1,000文字からなる英語の記事の中から「apple」という文字列を数えるようなプログラムを作成するとしましょう。

まず文章を読み込んで、空白が出てくるまでの文字の羅列を文字列とし、その文字列と「apple」という文字を比較し文字列が「apple」であればカウントします。もちろん「I」のような一文字を数える場合も文字比較することに変わりはありません。

このように、今回紹介した文字列の比較と検索を身につけると書けるプログラムの幅が広がります。今回学習した内容を基本としつつ自分のコードに積極的に取り入れながらぜひ有効活用してください。


.NET分野でのキャリアアップをお考えの方は、現在募集中の求人情報をご覧ください。

また、直接のエントリーも受け付けております。

エントリー(応募フォーム)

Search

Popular

reccomended

Categories

Tags