2009-03-06 3 views
105

문자열 $str이 부분 문자열 $test로 끝나는 지 여부를 테스트하는 표준 PHP 방법은 다음과 같습니다.PHP 문자열이 다른 문자열로 끝나는 지 여부에 대한 가장 효율적인 테스트는 무엇입니까?

$endsWith = substr($str, -strlen($test)) == $test 

가장 빠른 방법입니까?

+2

유사 : http://stackoverflow.com/questions/834303/php-startswith- and-endswith-functions – trante

+0

[''($ str) -> endsWith ($ test)'] (https://github.com/delight-im/PHP-Str/blob/8fd0c608d5496d43adaa899642c1cce047e076dc/src/Str. php # L117) 또는 ['s ($ str) -> endsWithIgnoreCase ($ test)'] (https://github.com/delight-im/PHP-Str/blob/8fd0c608d5496d43adaa899642c1cce047e076dc/src/Str.php#L131) [이 독립 실행 형 라이브러리] (https://github.com/delight-im/PHP-Str)에있는 유용한 정보입니다. – caw

답변

132

아싸 프가 말하는 것은 정확합니다. PHP에는 정확히 수행 할 함수가 내장되어 있습니다.

substr_compare($str, $test, strlen($str)-strlen($test), strlen($test)) === 0; 

$test 당신이 먼저 확인해야하므로, 경고를 줄 것 이상 $str PHP보다합니다.

function endswith($string, $test) { 
    $strlen = strlen($string); 
    $testlen = strlen($test); 
    if ($testlen > $strlen) return false; 
    return substr_compare($string, $test, $strlen - $testlen, $testlen) === 0; 
} 
+0

니스. Assaf가 지적한 것처럼, in-place를 비교하는 것이 substr()보다 더 빠를 것 같습니다. –

+2

mcrumley의 답변은 멋지지만 '=='대신 '==='를 사용해야합니다. '==='는 더 엄격하고 일반적으로 원하는 것을 수행하지만 '=='는 불쾌한 놀라움으로 이어질 수 있습니다. mcrumley의 세 번째 코드 스 니펫은 정확하지만 처음 두 개는 정확하지 않습니다. substr_compare()는 일부 오류 경우 false를 반환합니다. PHP에서는 false == 0이므로 코드 스 니펫은 문자열이 발견되었음을 알립니다. ===로, 이것은 일어나지 않습니다. –

+0

오늘 나는 PHP 5.5.11부터 제공 한 솔루션을 깨뜨리는 버그에 봉착했다. https://bugs.php.net/bug.php?id=67043 – user2180613

7

어떤 종류의 효율성이 중요한지에 따라 다릅니다.

귀하의 버전은 substr을 사용하여 추가 사본을 생성하기 때문에 더 많은 메모리를 사용합니다.

대체 버전은 원본 문자열에서 복사본을 만들지 않고 마지막 부분 문자열을 검색하지만 더 많은 테스트로 인해 느려질 수 있습니다.

아마도 가장 효율적인 방법은 -sterlen (테스트) 위치에서 char 끝에있는 char을 문자열 끝까지 비교하여 비교하는 것입니다. 그것은 당신이 할 수있는 비교의 최소한의 양이고 거의 추가 메모리가 사용되지 않습니다.

4

또 다른 방법은 strrpos function 사용하는 것입니다 :

strrpos($str, $test) == strlen($str) - strlen($test) 

을하지만 그것은하지 빠릅니다.

0

역순으로 strrchr()과 같은 함수를 사용하면 문자열의 끝에 가장 빨리 일치하는 데 도움이됩니다.

63

이 방법은 작은 조금 더 많은 메모리 비싼이지만, 빠른 : 당신은 바늘이 정확히 알고있을 때 당신은 하드 코드가 반전 할 수 있습니다

stripos(strrev($haystack), $reversed_needle) === 0; 

이, 최고입니다. 프로그래밍 방식으로 바늘을 뒤집어 놓으면 이전 방법보다 느려집니다.

function stringEndsWith($whole, $end) 
{ 
    return (strpos($whole, $end, strlen($whole) - strlen($end)) !== false); 
} 

솔직한, 나는이 PHP 4 일 거라고 생각 :

+0

그건 그냥 똑똑해! –

+0

독창성에 +1! –

+2

-1 나는 이것이 더 빠르다는 것을 진지하게 생각하며, 그것은 힘들다. haystack *이 바늘로 끝나지 않으면,'stripos'는 최악의 경우 전체 문자열을 반복 할 것이고'substr_compare'는 바늘의 길이를 비교할 것입니다. 예,'substr_compare'는 건초 더미의 길이를 계산할 필요가 있지만,이 방법은 *와 *를 복사하여 전체를 복사하고, 전체를 소문자로 변환하여 부팅 할 수 있어야합니다. –

7

다음은 문자열을 찾을 수에 어디에 잘 오프셋 strpos를 제공함으로써, 하나 개의 문자열이 서로 종료 여부를 확인하는 간단한 방법입니다.

2

나는 아래의 대답은 효율적이고도 간단 할 수 있기를 바랍니다 :

$content = "The main string to search"; 
$search = "search"; 
//For compare the begining string with case insensitive. 
if(stripos($content, $search) === 0) echo 'Yes'; 
else echo 'No'; 

//For compare the begining string with case sensitive. 
if(strpos($content, $search) === 0) echo 'Yes'; 
else echo 'No'; 

//For compare the ending string with case insensitive. 
if(stripos(strrev($content), strrev($search)) === 0) echo 'Yes'; 
else echo 'No'; 

//For compare the ending string with case sensitive. 
if(strpos(strrev($content), strrev($search)) === 0) echo 'Yes'; 
else echo 'No'; 
-1

이 순수 PHP는,이다 외부 함수를 호출하지 않고 s를 제외하고 strlen. 부정적인

function endsWith ($ends, $string) 
{ 
    $strLength = strlen ($string); 
    $endsLength = strlen ($ends); 
    for ($i = 0; $i < $endsLength; $i++) 
    { 
     if ($string [$strLength - $i - 1] !== $ends [$i]) 
      return false; 
    } 
    return true; 
} 
35
$endsWith = substr_compare($str, $test, -strlen($test)) === 0 

"는 문자열의 끝에서 계산을 시작합니다"오프셋.

+3

IMO 제공되는 솔루션 중에서 가장 좋은 것 중 하나입니다 –

+4

가능하면 대답 – FrancescoMM

+0

+200 수락해야합니다. 여기에서 핵심적인 통찰력은 음수 길이를 사용하면 문자열의 끝 부분을 얻는다는 것입니다. substr에 -ve 길이를 사용하고 $ test에 대해 ==를 수행 할 수도 있습니다. 다른 대답은 가난합니다. – Nick

1

이 빨리인지 아닌지 알고 있지만 너무 단일 문자 테스트, 이러한 작업을 위해하지 마십시오

(array_pop(str_split($string)) === $test) ? true : false; 
($string[strlen($string)-1] === $test) ? true : false; 
(strrev($string)[0] === $test) ? true : false; 
관련 문제