読みやすさはさておき、使用との間に識別可能な違い(おそらくパフォーマンス)があります
str.indexOf("src")
そして
str.match(/src/)
個人的にはmatch
(および正規表現)を好みますが、同僚は反対のように見えるようです。私たちはそれが重要かどうか疑問に思っていました...?
編集:
最初に、ワイルドカードなどを使用した完全な正規表現検索ではなく、(JQueryのクラス属性で識別子を取得するために)部分的なプレーン文字列マッチングを実行する関数用であると述べたはずです。
class='redBorder DisablesGuiClass-2345-2d73-83hf-8293'
その違いは次のとおりです。
string.indexOf('DisablesGuiClass-');
VS
string.match(/DisablesGuiClass-/)
RegExpは、実際にはindexOfよりも低速です( here で確認できます)。ただし、通常、これは問題にはなりません。 RegExpでは、文字列が適切にエスケープされていることも確認する必要がありますが、これはさらに考慮する必要があります。
これらの問題は別として、2つのツールが必要なことを正確に行う場合は、より単純なツールを選択してみませんか?
あなたの比較は完全に公平ではないかもしれません。 indexOf
はプレーン文字列で使用されるため、非常に高速です。 match
は正規表現を取ります-もちろん、比較では遅いかもしれませんが、正規表現の一致を行いたい場合は、indexOf
を使用することはできません。一方、正規表現エンジンは最適化でき、過去数年間でパフォーマンスが向上しています。
逐語的な文字列を探している場合、indexOf
で十分です。ただし、正規表現にはまだ1つのアプリケーションがあります。entire単語と一致させる必要があり、部分文字列の一致を避けたい場合、正規表現は「単語境界アンカー」を提供します。例えば:
indexOf('bar')
bar, fubar, barmy
でbar
を3回検索しますが、
match(/\bbar\b/)
長いWordの一部ではない場合にのみbar
と一致します。
コメントでわかるように、正規表現はindexOf
よりも高速である可能性があることを示すいくつかの比較が行われています-パフォーマンスが重要な場合は、コードをプロファイルする必要があります。
部分文字列の出現を大文字と小文字を区別せずに検索しようとしている場合、match
はindexOf
およびtoLowerCase()
ここで確認してください- http://jsperf.com/regexp-vs-indexof/152
str.indexOf('target')
またはstr.match(/target/)
のどちらを優先するかを尋ねます。他のポスターが示唆しているように、これらのメソッドのユースケースと戻り値の型は異なります。最初の質問は、「str
のどこで最初に_'target'
_を見つけることができますか?」 2番目は「str
は正規表現と一致しますか?一致する場合は、関連付けられているキャプチャグループと一致するものは何ですか?」
問題は、どちらも技術的には「文字列に部分文字列が含まれていますか?」という単純な質問をするように設計されていないことです。そのために明示的に設計されたものがあります:
_var doesStringContainTarget = /target/.test(str);
_
regex.test(string)
を使用することにはいくつかの利点があります。
str.match(/target/)
(およびライバルstr.indexOf('target')
)よりもパフォーマンスが高いstr
がundefined
またはnull
である場合、false
をスローする代わりにTypeError
(望ましい結果)が得られます。indexOf
を使用すると、プレーンテキストを検索する場合に理論的には正規表現よりも高速になりますが、パフォーマンスが懸念される場合は、自分で比較ベンチマークを行う必要があります。
match
を好み、それがあなたのニーズに十分に速いなら、それを選んでください。
価値があることについては、これについてあなたの同僚に同意します。プレーン文字列を検索するときはindexOf
を使用し、正規表現によって提供される追加機能が必要なときだけmatch
などを使用します。
パフォーマンスに関しては、indexOf
は少なくともmatch
よりもわずかに高速になります。それはすべて特定の実装に帰着します。どちらを使用するかを決めるときは、次の質問を自問してください。
整数インデックスで十分ですか、またはRegExp一致結果の機能が必要ですか?
他の回答で対処されているパフォーマンスへの影響は別として、各メソッドの戻り値が異なることに注意することが重要です。そのため、ロジックを変更せずにメソッドを単に置き換えることはできません。
.indexOf
の戻り値:integer
String
から検索を開始し、指定された値が最初に現れる呼び出し元fromIndex
オブジェクト内のインデックス。
値が見つからない場合、-1
を返します。
.match
の戻り値:array
一致結果全体と、括弧でキャプチャされた一致結果を含む配列。
一致するものがなかった場合、null
を返します。
呼び出し文字列beginsが指定された値の場合、.indexOf
は0
を返すため、単純な真実性テストは失敗します。
例:
このクラスを指定…
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.
}
ここでは、(比較的)文字列を検索するためのすべての可能な方法
// 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);
Es6 includeのベンチマークは特別にねじれているようです。コメントを読んでください。
一致する必要がない場合。 =>正規表現が必要なため、testを使用します。それ以外の場合、es6includesまたはindexOfそれでもtestvsindexOfは近い。
それらは同じように見えます: https://jsperf.com/array-indexof-vs-includes/4 (それが違う場合、それはより奇妙になるでしょう、彼らは違いを除いてほとんど同じことを行います彼らが公開すること チェックしてください )
そして、私自身のベンチマークテストのために。ここにあります http://jsben.ch/fFnA あなたはそれをテストすることができます(ブラウザに依存します)[複数回テスト]ここでそれがどのように実行されたか(複数のindexOfを実行し、1つのビートを含み、近いです)。したがって、それらは同じです。 [ここでは、上記の記事と同じテストプラットフォームを使用しています]。
そして、ここでは長いテキストバージョン(8倍長い) http://jsben.ch/wSBA2
chromeとfirefox、同じことの両方をテストしました。
Jsben.chはメモリオーバーフローを処理しない(または制限が正しくあり、メッセージを表示しない)ため、8つ以上のテキスト複製を追加すると結果が正しくなくなる可能性があります(8つはうまく機能します)。しかし、結論は非常に大きなテキストの場合、3つすべてが同じように機能することです。それ以外の場合、短いindexOfとincludeは同じであり、テストは少し遅くなります。またはchrome(firefox 60の方が遅い)のように見えます。
Jsben.chに注意してください:一貫性のない結果が得られたとしても驚かないでください。別の時間を試して、それが一貫しているかどうかを確認します。ブラウザを変更してください。時々、まったく間違って動作することがあります。メモリのバグまたは不適切な処理。か何か。
例:
ここでもjsperfのベンチマーク(より良い詳細、および複数のブラウザーのグラフの処理)
(上部はクロム)
通常のテキストhttps://jsperf.com/indexof-vs-includes-vs-test-2019
resume:includeとindexOfのパフォーマンスは同じです。テストが遅くなります。
ロングテキスト(通常よりも12倍長い) https://jsperf.com/indexof-vs-includes-vs-test-2019 -long-text-str /
resume:3つすべてが同じことを実行します。 (クロームとFirefox)
非常に短い文字列https://jsperf.com/indexof-vs-includes-vs-test-2019-too-short-string /
resume:includeとindexOfは同じことを実行し、テストを遅くします。
注:上記のベンチマークについて。 非常に短い文字列バージョン(jsperf)では、chromeに大きなエラーがありました。私の目で見る。 indexOfの両方で約60個のサンプルが実行され、同じ方法が含まれています(多くの時間を繰り返しました)。そして、テストを少し減らして、とても遅くします。間違ったグラフにだまされないでください。明らかに間違っています。 Firefoxでも同じテスト作業で問題ありません。確かにバグです。
ここの図:(最初の画像はFirefoxでのテストでした) waaaa。突然indexOfがスーパーマンになりました。しかし、私が言ったように、私はテストを行い、サンプル数を見て、それはおよそ60でした。indexOfとincludeの両方は同じことをしました。 jsprefのバグ。これを除いて(おそらくメモリ制限に関連する問題のため)、残りはすべて一貫性があり、より詳細を提供します。そして、あなたはリアルタイムでどれだけ簡単に起こるかを見る。
indexOf vs include=>同じパフォーマンス
test=>短い文字列やテキストの場合は遅くなる可能性があります。長いテキストでも同じです。そして、正規表現エンジンが追加するオーバーヘッドのためにそれは理にかなっています。 chromeではまったく問題ではないようです。
internet Explorer 8はindexOf
を理解しないことに注意してください。ただし、IE8を使用しているユーザーがいない場合(Googleアナリティクスで通知される場合)、この回答を省略します。 IE8を修正するための可能な解決策: Internet Explorerブラウザー用のJavaScriptでArray indexOf()を修正する方法
部分文字列の存在には常にindexOf
を使用し、実際に必要な場合にのみmatch
を使用します。つまり、src
を含む可能性のある文字列でWordaltsrc
を検索する場合は、aString.match(/\bsrc\b/)
が実際により適切です。