web-dev-qa-db-ja.com

JavaScript:文字列を検索するときのindexOf対Match?

読みやすさはさておき、使用との間に識別可能な違い(おそらくパフォーマンス)があります

str.indexOf("src") 

そして

str.match(/src/)

個人的にはmatch(および正規表現)を好みますが、同僚は反対のように見えるようです。私たちはそれが重要かどうか疑問に思っていました...?

編集:

最初に、ワイルドカードなどを使用した完全な正規表現検索ではなく、(JQueryのクラス属性で識別子を取得するために)部分的なプレーン文字列マッチングを実行する関数用であると述べたはずです。

class='redBorder DisablesGuiClass-2345-2d73-83hf-8293' 

その違いは次のとおりです。

string.indexOf('DisablesGuiClass-');

VS

string.match(/DisablesGuiClass-/)
62
indra

RegExpは、実際にはindexOfよりも低速です( here で確認できます)。ただし、通常、これは問題にはなりません。 RegExpでは、文字列が適切にエスケープされていることも確認する必要がありますが、これはさらに考慮する必要があります。

これらの問題は別として、2つのツールが必要なことを正確に行う場合は、より単純なツールを選択してみませんか?

54
David Tang

あなたの比較は完全に公平ではないかもしれません。 indexOfはプレーン文字列で使用されるため、非常に高速です。 matchは正規表現を取ります-もちろん、比較では遅いかもしれませんが、正規表現の一致を行いたい場合は、indexOfを使用することはできません。一方、正規表現エンジンは最適化でき、過去数年間でパフォーマンスが向上しています。

逐語的な文字列を探している場合、indexOfで十分です。ただし、正規表現にはまだ1つのアプリケーションがあります。entire単語と一致させる必要があり、部分文字列の一致を避けたい場合、正規表現は「単語境界アンカー」を提供します。例えば:

indexOf('bar')

bar, fubar, barmybarを3回検索しますが、

match(/\bbar\b/)

長いWordの一部ではない場合にのみbarと一致します。

コメントでわかるように、正規表現はindexOfよりも高速である可能性があることを示すいくつかの比較が行われています-パフォーマンスが重要な場合は、コードをプロファイルする必要があります。

19
Tim Pietzcker

部分文字列の出現を大文字と小文字を区別せずに検索しようとしている場合、matchindexOfおよびtoLowerCase()

ここで確認してください- http://jsperf.com/regexp-vs-indexof/152

9
Yogesh Mangaj

str.indexOf('target')またはstr.match(/target/)のどちらを優先するかを尋ねます。他のポスターが示唆しているように、これらのメソッドのユースケースと戻り値の型は異なります。最初の質問は、「strのどこで最初に_'target'_を見つけることができますか?」 2番目は「strは正規表現と一致しますか?一致する場合は、関連付けられているキャプチャグループと一致するものは何ですか?」

問題は、どちらも技術的には「文字列に部分文字列が含まれていますか?」という単純な質問をするように設計されていないことです。そのために明示的に設計されたものがあります:

_var doesStringContainTarget = /target/.test(str);
_

regex.test(string)を使用することにはいくつかの利点があります。

  1. ブール値を返します。
  2. str.match(/target/)(およびライバルstr.indexOf('target'))よりもパフォーマンスが高い
  3. 何らかの理由でstrundefinedまたはnullである場合、falseをスローする代わりにTypeError(望ましい結果)が得られます。
6
elreimundo

indexOfを使用すると、プレーンテキストを検索する場合に理論的には正規表現よりも高速になりますが、パフォーマンスが懸念される場合は、自分で比較ベンチマークを行う必要があります。

matchを好み、それがあなたのニーズに十分に速いなら、それを選んでください。

価値があることについては、これについてあなたの同僚に同意します。プレーン文字列を検索するときはindexOfを使用し、正規表現によって提供される追加機能が必要なときだけmatchなどを使用します。

5
LukeH

パフォーマンスに関しては、indexOfは少なくともmatchよりもわずかに高速になります。それはすべて特定の実装に帰着します。どちらを使用するかを決めるときは、次の質問を自問してください。

整数インデックスで十分ですか、またはRegExp一致結果の機能が必要ですか?

4
ChaosPandion

戻り値は異なります

他の回答で対処されているパフォーマンスへの影響は別として、各メソッドの戻り値が異なることに注意することが重要です。そのため、ロジックを変更せずにメソッドを単に置き換えることはできません。

.indexOf の戻り値:integer

Stringから検索を開始し、指定された値が最初に現れる呼び出し元fromIndexオブジェクト内のインデックス。
値が見つからない場合、-1を返します。

.match の戻り値:array

一致結果全体と、括弧でキャプチャされた一致結果を含む配列。
一致するものがなかった場合、nullを返します

呼び出し文字列beginsが指定された値の場合、.indexOf0を返すため、単純な真実性テストは失敗します。

例:

このクラスを指定…

class='DisablesGuiClass-2345-2d73-83hf-8293 redBorder' 

…それぞれの戻り値は異なります:

//  returns `0`, evaluates to `false`
if (string.indexOf('DisablesGuiClass-')) {
    … // this block is skipped.
}

vs。

//  returns `["DisablesGuiClass-"]`, evaluates to `true`
if (string.match(/DisablesGuiClass-/)) { 
    … // this block is run.
}

.indexOfからの戻り値を使用して真実のテストを実行する正しい方法は、-1に対してテストすることです。

if (string.indexOf('DisablesGuiClass-') !== -1) {
//  ^returns `0`                        ^evaluates to `true`
    … // this block is run.
}
3
gfullam

ここでは、(比較的)文字列を検索するためのすべての可能な方法

// 1. include(ES6で導入)

var string = "string to search for substring",
    substring = "sea";
string.includes(substring);

// 2. string.indexOf

var string = "string to search for substring",
    substring = "sea";
string.indexOf(substring) !== -1;

// 3. RegExp:テスト

var string = "string to search for substring",
    expr = /sea/;  // no quotes here
expr.test(string);

// 4. string.match

var string = "string to search for substring",
    expr = "/sea/";
string.match(expr);

// 5。 string.search

var string = "string to search for substring",
    expr = "/sea/";
string.search(expr);

ここにsrc: https://koukia.ca/top-6-ways-to-search-for-a-string-in-javascript-and-performance-benchmarks-ce3e9b81ad31

Es6 includeのベンチマークは特別にねじれているようです。コメントを読んでください。

再開中:

一致する必要がない場合。 =>正規表現が必要なため、testを使用します。それ以外の場合、es6includesまたはindexOfそれでもtestvsindexOfは近い。

そして、インクルードvs indexOfの場合:

それらは同じように見えます: https://jsperf.com/array-indexof-vs-includes/4 (それが違う場合、それはより奇妙になるでしょう、彼らは違いを除いてほとんど同じことを行います彼らが公開すること チェックしてください

そして、私自身のベンチマークテストのために。ここにあります http://jsben.ch/fFnA あなたはそれをテストすることができます(ブラウザに依存します)[複数回テスト]ここでそれがどのように実行されたか(複数のindexOfを実行し、1つのビートを含み、近いです)。したがって、それらは同じです。 [ここでは、上記の記事と同じテストプラットフォームを使用しています]。

enter image description hereenter image description here

そして、ここでは長いテキストバージョン(8倍長い) http://jsben.ch/wSBA2

enter image description here

chromeとfirefox、同じことの両方をテストしました。

Jsben.chはメモリオーバーフローを処理しない(または制限が正しくあり、メッセージを表示しない)ため、8つ以上のテキスト複製を追加すると結果が正しくなくなる可能性があります(8つはうまく機能します)。しかし、結論は非常に大きなテキストの場合、3つすべてが同じように機能することです。それ以外の場合、短いindexOfとincludeは同じであり、テストは少し遅くなります。またはchrome(firefox 60の方が遅い)のように見えます。

Jsben.chに注意してください:一貫性のない結果が得られたとしても驚かないでください。別の時間を試して、それが一貫しているかどうかを確認します。ブラウザを変更してください。時々、まったく間違って動作することがあります。メモリのバグまたは不適切な処理。か何か。

例:

enter image description here

ここでもjsperfのベンチマーク(より良い詳細、および複数のブラウザーのグラフの処理)

(上部はクロム)

通常のテキストhttps://jsperf.com/indexof-vs-includes-vs-test-2019
resume:includeとindexOfのパフォーマンスは同じです。テストが遅くなります。

enter image description hereenter image description here (3つすべてがchromで同じことを行うようです)

ロングテキスト(通常よりも12倍長い) https://jsperf.com/indexof-vs-includes-vs-test-2019 -long-text-str /
resume:3つすべてが同じことを実行します。 (クロームとFirefox) enter image description here

非常に短い文字列https://jsperf.com/indexof-vs-includes-vs-test-2019-too-short-string /
resume:includeとindexOfは同じことを実行し、テストを遅くします。

enter image description here

注:上記のベンチマークについて。 非常に短い文字列バージョン(jsperf)では、chromeに大きなエラーがありました。私の目で見る。 indexOfの両方で約60個のサンプルが実行され、同じ方法が含まれています(多くの時間を繰り返しました)。そして、テストを少し減らして、とても遅くします。間違ったグラフにだまされないでください。明らかに間違っています。 Firefoxでも同じテスト作業で問題ありません。確かにバグです。

ここの図:(最初の画像はFirefoxでのテストでした) enter image description here waaaa。突然indexOfがスーパーマンになりました。しかし、私が言ったように、私はテストを行い、サンプル数を見て、それはおよそ60でした。indexOfとincludeの両方は同じことをしました。 jsprefのバグ。これを除いて(おそらくメモリ制限に関連する問題のため)、残りはすべて一貫性があり、より詳細を提供します。そして、あなたはリアルタイムでどれだけ簡単に起こるかを見る。

最終履歴書

indexOf vs include=>同じパフォーマンス

test=>短い文字列やテキストの場合は遅くなる可能性があります。長いテキストでも同じです。そして、正規表現エンジンが追加するオーバーヘッドのためにそれは理にかなっています。 chromeではまったく問題ではないようです。

3
Mohamed Allal

internet Explorer 8はindexOfを理解しないことに注意してください。ただし、IE8を使用しているユーザーがいない場合(Googleアナリティクスで通知される場合)、この回答を省略します。 IE8を修正するための可能な解決策: Internet Explorerブラウザー用のJavaScriptでArray indexOf()を修正する方法

0
NoWomenNoCry

部分文字列の存在には常にindexOfを使用し、実際に必要な場合にのみmatchを使用します。つまり、srcを含む可能性のある文字列でWordaltsrcを検索する場合は、aString.match(/\bsrc\b/)が実際により適切です。

0
Walf