자바 스크립트 : indexOf 대 일치 문자열 검색?
가독성을 제쳐두고, 사용하는 것 사이에 눈에 띄는 차이 (아마도 성능)가 있습니까?
str.indexOf("src")
과
str.match(/src/)
나는 개인적으로 match
(그리고 regexp) 선호 하지만 동료들은 다른 방향으로가는 것 같습니다. 그게 중요한지 궁금해서 ...?
편집하다:
나는 처음에 이것이 와일드 카드 등을 사용한 전체 정규식 검색이 아니라 부분 일반 문자열 일치 (JQuery의 클래스 속성에서 식별자를 선택하기 위해)를 수행 할 함수에 대한 것이라고 말 했어야했습니다.
class='redBorder DisablesGuiClass-2345-2d73-83hf-8293'
따라서 다음과 같은 차이점이 있습니다.
string.indexOf('DisablesGuiClass-');
VS
string.match(/DisablesGuiClass-/)
RegExp는 실제로 indexOf ( 여기에서 볼 수 있음)보다 느리지 만 일반적으로 이것은 문제가되지 않습니다. RegExp를 사용하면 문자열이 적절하게 이스케이프되었는지 확인해야합니다. 이는 고려할 추가 사항입니다.
두 가지 문제를 제쳐두고 두 도구가 필요한 작업을 정확히 수행한다면 더 간단한 도구를 선택하는 것은 어떨까요?
귀하의 비교는 완전히 공정하지 않을 수 있습니다. indexOf
일반 문자열과 함께 사용되므로 매우 빠릅니다. match
정규식을 사용합니다. 물론 비교하면 느릴 수 있지만 정규식 일치를 수행하려는 경우 indexOf
. 반면 정규식 엔진은 최적화 될 수 있으며 지난 몇 년 동안 성능이 향상되었습니다.
귀하의 경우에는 축어 문자열을 찾고있는 indexOf
것으로 충분합니다. 하지만 정규 표현식에 대한 애플리케이션은 여전히 하나 있습니다. 전체 단어 를 일치시켜야하고 부분 문자열 일치를 피하려면 정규 표현식이 "단어 경계 앵커"를 제공합니다. 예를 들면 :
indexOf('bar')
bar
에서 세 번 찾을 수 bar, fubar, barmy
있지만
match(/\bbar\b/)
bar
더 긴 단어의 일부가 아닌 경우 에만 일치 합니다.
주석에서 볼 수 있듯이 정규식이 더 빠를 수 있음을 보여주는 몇 가지 비교가 수행되었습니다. indexOf
성능이 중요하다면 코드를 프로파일 링해야 할 수도 있습니다.
대소 문자 를 구분하지 않고 부분 문자열 발생을 검색하려는 경우 및 match
조합보다 더 빠른 것 같습니다.indexOf
toLowerCase()
여기에서 확인하십시오 -http : //jsperf.com/regexp-vs-indexof/152
당신은 여부를 질문 str.indexOf('target')
하거나 str.match(/target/)
선호한다. 다른 포스터에서 제안했듯이 이러한 메서드의 사용 사례와 반환 유형은 다릅니다. 첫 번째는 " str
처음 찾을 수 있는 곳은 어디 'target'
입니까?" 두 번째는 " str
정규식과 일치합니까? 그렇다면 연관된 캡처 그룹에 대한 모든 일치는 무엇입니까?"라고 묻습니다.
문제는 기술적으로 어느 누구도 "문자열에 부분 문자열이 포함되어 있습니까?"라는 간단한 질문을하도록 설계되지 않았다는 것입니다. 이를 위해 명시 적으로 설계된 것이 있습니다.
var doesStringContainTarget = /target/.test(str);
다음을 사용하면 몇 가지 이점이 있습니다 regex.test(string)
.
- 그것은 당신이 관심을 갖는 부울을 반환합니다.
str.match(/target/)
(및 라이벌str.indexOf('target')
) 보다 성능이 뛰어납니다.- 어떤 이유로 경우
str
입니다undefined
또는null
, 당신은 얻을 것이다false
대신을 던지는 (원하는 결과를)TypeError
사용하여 indexOf
, 이론적으로, 빨리 당신이 그냥 일반 텍스트를 검색하는 정규식보다해야하지만, 성능에 대해 우려하는 경우 당신은 몇 가지 비교 벤치 마크를 직접해야한다.
당신이 선호 match
하고 당신의 필요에 충분히 빠르 다면 그것을 위해 가십시오.
그만한 가치에 대해서는 동료들과 동의합니다. 저는 indexOf
일반 문자열을 검색 할 때 사용 match
하고 정규 표현식에서 제공하는 추가 기능이 필요할 때만 etc를 사용 합니다.
여기에서 가능한 모든 방법 (상대적으로) 문자열 검색
// 1. 포함 (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 포함에 대해 특별히 뒤틀린 것 같습니다. 주석을 읽으십시오.
이력서 :
성냥이 필요하지 않으면. => 정규식이 필요하므로 test를 사용하십시오 . 그렇지 않으면 es6 에는 또는 indexOf가 포함됩니다 . 여전히 테스트 대 indexOf 는 가깝습니다.
포함 대 indexOf의 경우 :
그들은 똑같은 것 같습니다 : https://jsperf.com/array-indexof-vs-includes/4 (다르면 이상 할 것입니다.이를 확인 하는 차이점을 제외하고는 대부분 동일하게 수행합니다 )
그리고 내 자신의 벤치 마크 테스트를 위해. 여기에 http://jsben.ch/fFnA0 테스트 할 수 있습니다 (브라우저에 따라 다름) [여러 번 테스트] 여기에서 수행 방법 (여러 실행 indexOf 및 하나의 비트를 포함하며 가깝습니다). 그래서 그들은 동일합니다. [여기에서는 위의 문서와 동일한 테스트 플랫폼 사용].
그리고 여기에 긴 텍스트 버전 (8 배 더 긴) http://jsben.ch/wSBA2
크롬과 파이어 폭스를 모두 테스트했습니다.
jsben.ch가 메모리 오버플로를 처리하지 않거나 (또는 제한이 올바르게 있습니다. 메시지를 표시하지 않음) 8 개 이상의 텍스트 중복을 추가하면 결과가 잘못 될 수 있습니다 (8 개가 잘 작동 함). 그러나 결론은 매우 큰 텍스트의 경우 세 가지 모두 동일한 방식으로 수행됩니다. 그렇지 않으면 짧은 indexOf 및 포함이 동일하고 약간 느리게 테스트됩니다. 또는 크롬에서 보이는 것과 동일 할 수 있습니다 (firefox 60이 더 느림).
jsben.ch에주의하십시오 : 결과가 일관되지 않더라도 놀라지 마십시오. 다른 시간을 시도하고 일관성이 있는지 확인하십시오. 브라우저를 변경하면 때로는 완전히 잘못 실행됩니다. 버그 또는 잘못된 메모리 처리. 또는 뭔가.
전의:
여기에도 jsperf에 대한 내 벤치 마크 (더 나은 세부 정보 및 여러 브라우저에 대한 그래프 처리)
(상단은 크롬)
일반 텍스트 https://jsperf.com/indexof-vs-includes-vs-test-2019
resume : includes와 indexOf는 동일한 성능을 갖습니다. 천천히 테스트하십시오.
(세 가지 모두 chrom에서 동일하게 수행하는 것처럼 보임)
긴 텍스트 (일반보다 12 배 더 길어짐) https://jsperf.com/indexof-vs-includes-vs-test-2019-long-text-str/
resume : 세 가지 모두 동일한 작업을 수행합니다. (크롬 및 파이어 폭스)
매우 짧은 문자열 https://jsperf.com/indexof-vs-includes-vs-test-2019-too-short-string/
resume : includes와 indexOf는 동일하게 수행하고 더 느리게 테스트합니다.
Note: about the benchmark above. For the very short string version (jsperf) had an big error for chrome. Seeing by my eyes. around 60 sample was run for both indexOf and includes same way (repeated a lot of time). And test a little bit less and so slower. don't be fooled with the wrong graph. It's clear wrong. Same test work ok for firefox, surely it's a bug.
Here the illustration: (the first image was the test on firefox) waaaa. Suddenly indexOf became superman. But as i said i did the test, and looked at the number of samples it was around 60. Both indexOf and includes and they performed the same. A bug on jspref. Except for this one (maybe because of a memory restriction related problem) all the rest was consistent, it give more details. And you see how many simple happen in real time.
Final resume
indexOf vs includes => Same performance
test => can be slower for short strings or text. And the same for long texts. And it make sense for the overhead that the regex engine add. In chrome it seemed it doesn't matter at all.
Performance wise indexOf
will at the very least be slightly faster than match
. It all comes down to the specific implementation. When deciding which to use ask yourself the following question:
Will an integer index suffice or do I need the functionality of a RegExp match result?
The return values are different
Aside from the performance implications, which are addressed by other answers, it is important to note that the return values for each method are different; so the methods cannot merely be substituted without also changing your logic.
Return value of .indexOf
: integer
The index within the calling
String
object of the first occurrence of the specified value, starting the search atfromIndex
.
Returns-1
if the value is not found.
Return value of .match
: array
An Array containing the entire match result and any parentheses-captured matched results.
Returnsnull
if there were no matches.
Because .indexOf
returns 0
if the calling string begins with the specified value, a simple truthy test will fail.
For example:
Given this class…
class='DisablesGuiClass-2345-2d73-83hf-8293 redBorder'
…the return values for each would differ:
// 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.
}
The correct way to run a truthy test with the return from .indexOf
is to test against -1
:
if (string.indexOf('DisablesGuiClass-') !== -1) {
// ^returns `0` ^evaluates to `true`
… // this block is run.
}
always use indexOf
for existence of substrings and match
only when you actually need it. i.e. if you were searching for the word src
in a string that could also contain altsrc
then aString.match(/\bsrc\b/)
is indeed more appropriate.
Internet Explorer 8은 indexOf
. 그러나 사용자 중 아무도 ie8을 사용하지 않는다면 (구글 분석에서 알려줄 것입니다)이 답변을 생략하십시오. IE8을 수정하는 가능한 솔루션 : Internet Explorer 브라우저 용 JavaScript에서 Array indexOf ()를 수정하는 방법
참고 URL : https://stackoverflow.com/questions/4757438/javascript-indexof-vs-match-when-searching-strings
'Development Tip' 카테고리의 다른 글
Vue 프로젝트에서보기와 구성 요소 폴더의 차이점은 무엇입니까? (0) | 2020.11.21 |
---|---|
모두 없음보다 큰가요? (0) | 2020.11.21 |
사용 가능한 모든 matplotlib 백엔드 목록 (0) | 2020.11.21 |
모든 셀러리 작업의 로그 메시지를 단일 파일로 전송 (0) | 2020.11.21 |
div가 나머지 높이를 차지하도록 만드는 방법은 무엇입니까? (0) | 2020.11.21 |