index - php 문자열 위치




PHP에서 startsWith() 및 endsWith() 함수 (20)

가장 빠른 끝 () 해결책 :

# Checks if a string ends in a string
function endsWith($haystack, $needle) {
    return substr($haystack,-strlen($needle))===$needle;
}

기준:

# This answer
function endsWith($haystack, $needle) {
    return substr($haystack,-strlen($needle))===$needle;
}

# Accepted answer
function endsWith2($haystack, $needle) {
    $length = strlen($needle);

    return $length === 0 ||
    (substr($haystack, -$length) === $needle);
}

# Second most-voted answer
function endsWith3($haystack, $needle) {
    // search forward starting from end minus needle length characters
    if ($needle === '') {
        return true;
    }
    $diff = \strlen($haystack) - \strlen($needle);
    return $diff >= 0 && strpos($haystack, $needle, $diff) !== false;
}

# Regex answer
function endsWith4($haystack, $needle) {
    return preg_match('/' . preg_quote($needle, '/') . '$/', $haystack);
}

function timedebug() {
    $test = 10000000;

    $time1 = microtime(true);
    for ($i=0; $i < $test; $i++) {
        $tmp = endsWith('TestShortcode', 'Shortcode');
    }
    $time2 = microtime(true);
    $result1 = $time2 - $time1;

    for ($i=0; $i < $test; $i++) {
        $tmp = endsWith2('TestShortcode', 'Shortcode');
    }
    $time3 = microtime(true);
    $result2 = $time3 - $time2;

    for ($i=0; $i < $test; $i++) {
        $tmp = endsWith3('TestShortcode', 'Shortcode');
    }
    $time4 = microtime(true);
    $result3 = $time4 - $time3;

    for ($i=0; $i < $test; $i++) {
        $tmp = endsWith4('TestShortcode', 'Shortcode');
    }
    $time5 = microtime(true);
    $result4 = $time5 - $time4;

    echo $test.'x endsWith: '.$result1.' seconds # This answer<br>';
    echo $test.'x endsWith2: '.$result4.' seconds # Accepted answer<br>';
    echo $test.'x endsWith3: '.$result2.' seconds # Second most voted answer<br>';
    echo $test.'x endsWith4: '.$result3.' seconds # Regex answer<br>';
    exit;
}
timedebug();

벤치 마크 결과 :

10000000x endsWith: 1.5760900974274 seconds # This answer
10000000x endsWith2: 3.7102129459381 seconds # Accepted answer
10000000x endsWith3: 1.8731069564819 seconds # Second most voted answer
10000000x endsWith4: 2.1521229743958 seconds # Regex answer

문자열을 가져 와서 지정된 문자 / 문자열로 시작하거나 끝나는 경우 반환하는 두 가지 함수를 작성하려면 어떻게해야합니까?

예 :

$str = '|apples}';

echo startsWith($str, '|'); //Returns true
echo endsWith($str, '}'); //Returns true

2016 년 8 월 23 일자로 업데이트 됨

기능들

function substr_startswith($haystack, $needle) {
    return substr($haystack, 0, strlen($needle)) === $needle;
}

function preg_match_startswith($haystack, $needle) {
    return preg_match('~' . preg_quote($needle, '~') . '~A', $haystack) > 0;
}

function substr_compare_startswith($haystack, $needle) {
    return substr_compare($haystack, $needle, 0, strlen($needle)) === 0;
}

function strpos_startswith($haystack, $needle) {
    return strpos($haystack, $needle) === 0;
}

function strncmp_startswith($haystack, $needle) {
    return strncmp($haystack, $needle, strlen($needle)) === 0;
}

function strncmp_startswith2($haystack, $needle) {
    return $haystack[0] === $needle[0]
        ? strncmp($haystack, $needle, strlen($needle)) === 0
        : false;
}

테스트

echo 'generating tests';
for($i = 0; $i < 100000; ++$i) {
    if($i % 2500 === 0) echo '.';
    $test_cases[] = [
        random_bytes(random_int(1, 7000)),
        random_bytes(random_int(1, 3000)),
    ];
}
echo "done!\n";


$functions = ['substr_startswith', 'preg_match_startswith', 'substr_compare_startswith', 'strpos_startswith', 'strncmp_startswith', 'strncmp_startswith2'];
$results = [];

foreach($functions as $func) {
    $start = microtime(true);
    foreach($test_cases as $tc) {
        $func(...$tc);
    }
    $results[$func] = (microtime(true) - $start) * 1000;
}

asort($results);

foreach($results as $func => $time) {
    echo "$func: " . number_format($time, 1) . " ms\n";
}

결과 (PHP 7.0.9)

(가장 빠른 것으로 분류 됨)

strncmp_startswith2: 40.2 ms
strncmp_startswith: 42.9 ms
substr_compare_startswith: 44.5 ms
substr_startswith: 48.4 ms
strpos_startswith: 138.7 ms
preg_match_startswith: 13,152.4 ms

결과 (PHP 5.3.29)

(가장 빠른 것으로 분류 됨)

strncmp_startswith2: 477.9 ms
strpos_startswith: 522.1 ms
strncmp_startswith: 617.1 ms
substr_compare_startswith: 706.7 ms
substr_startswith: 756.8 ms
preg_match_startswith: 10,200.0 ms

startswith_benchmark.php


간단히 말해서 :

function startsWith($str, $needle){
   return substr($str, 0, strlen($needle)) === $needle;
}

function endsWith($str, $needle){
   $length = strlen($needle);
   return !$length || substr($str, - $length) === $needle;
}

나는 보통 underscore-php 와 같은 라이브러리를 사용 underscore-php .

require_once("vendor/autoload.php"); //use if needed
use Underscore\Types\String; 

$str = "there is a string";
echo( String::startsWith($str, 'the') ); // 1
echo( String::endsWith($str, 'ring')); // 1   

라이브러리는 다른 편리한 기능으로 가득 차 있습니다.


다음은 임시 문자열을 도입하지 않는 두 가지 기능입니다. 바늘이 상당히 클 때 유용 할 수 있습니다.

function startsWith($haystack, $needle)
{
    return strncmp($haystack, $needle, strlen($needle)) === 0;
}

function endsWith($haystack, $needle)
{
    return $needle === '' || substr_compare($haystack, $needle, -strlen($needle)) === 0;
}

다음은 허용 된 답변의 멀티 바이트 안전 버전입니다. UTF-8 문자열에서 제대로 작동합니다.

function startsWith($haystack, $needle)
{
    $length = mb_substr($needle, 'UTF-8');
    return (mb_substr($haystack, 0, $length, 'UTF-8') === $needle);
}

function endsWith($haystack, $needle)
{
    $length = mb_strlen($needle, 'UTF-8');
    return $length === 0 ||
        (mb_substr($haystack, -$length, $length, 'UTF-8') === $needle);
}

아래 답변이 효율적이고 간단 할 수 있기를 바랍니다.

$content = "The main string to search";
$search = "T";
//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';

의 answer 은 믿을 수 없을 정도로 철저하지만, 불행하게도 제공된 벤치 마크는 매우 중요하고 해로운 감독을합니다.

바늘과 건초 더미의 모든 바이트가 완전히 무작위이기 때문에 첫 번째 바이트에서 needle-haystack 쌍이 다를 확률은 99.609375 %입니다. 즉, 평균적으로 100000 쌍 중 약 99609 개가 첫 번째 바이트에서 달라집니다 . 즉, 벤치 마크는 strncmp_startswith2 가 수행하는 것처럼 첫 번째 바이트를 명시 적으로 검사하는 startswith 구현쪽으로 크게 치우쳐 있습니다.

테스트 생성 루프가 대신 다음과 같이 구현 된 경우 :

echo 'generating tests';
for($i = 0; $i < 100000; ++$i) {
    if($i % 2500 === 0) echo '.';

    $haystack_length = random_int(1, 7000);
    $haystack = random_bytes($haystack_length);

    $needle_length = random_int(1, 3000);
    $overlap_length = min(random_int(0, $needle_length), $haystack_length);
    $needle = ($needle_length > $overlap_length) ?
        substr($haystack, 0, $overlap_length) . random_bytes($needle_length - $overlap_length) :
        substr($haystack, 0, $needle_length);

    $test_cases[] = [$haystack, $needle];
}
echo " done!<br />";

벤치 마크 결과는 약간 다른 이야기를합니다.

strncmp_startswith: 223.0 ms
substr_startswith: 228.0 ms
substr_compare_startswith: 238.0 ms
strncmp_startswith2: 253.0 ms
strpos_startswith: 349.0 ms
preg_match_startswith: 20,828.7 ms

물론,이 벤치 마크는 여전히 완벽하게 편향되지는 않지만 부분적으로 일치하는 바늘이 주어 지더라도 알고리즘의 효율성을 테스트합니다.


이 질문에는 이미 많은 해답이 있지만 어떤 경우에는 모든 것보다 더 간단한 것을 얻을 수 있습니다. 찾으려는 문자열이 알려진 경우 (하드 코드 된 경우) 인용 부호없이 일반 표현식을 사용할 수 있습니다.

문자열이 'ABC'로 시작하는지 확인하십시오.

preg_match('/^ABC/', $myString); // "^" here means beginning of string

'ABC'로 끝납니다.

preg_match('/ABC$/', $myString); // "$" here means end of string

간단한 경우 문자열이 슬래시로 끝나는 지 확인하고 싶습니다.

preg_match('#/$#', $myPath);   // Use "#" as delimiter instead of escaping slash

이점 : 매우 짧고 간단하기 때문에 위와 같이 함수를 정의 할 필요가 없습니다 (예 : endsWith() ).

그러나 다시 - 이것은 모든 경우에 대한 해결책은 아니며, 매우 구체적인 사례입니다.


이것은 효과가있다.

function startsWith($haystack, $needle) {
     return substr($haystack, 0, strlen($needle)) == $needle;
}

출처 : https://.com/a/4419658


지금까지의 모든 대답은 불필요한 작업, strlen calculations , string allocations (substr) 등을 수행하는 것처럼 보입니다. 'strpos''stripos' 함수는 $haystack 에서 $haystack $needle 의 첫 번째 발생 색인을 반환합니다.

function startsWith($haystack,$needle,$case=true)
{
    if ($case)
        return strpos($haystack, $needle, 0) === 0;

    return stripos($haystack, $needle, 0) === 0;
}

function endsWith($haystack,$needle,$case=true)
{
    $expectedPosition = strlen($haystack) - strlen($needle);

    if ($case)
        return strrpos($haystack, $needle, 0) === $expectedPosition;

    return strripos($haystack, $needle, 0) === $expectedPosition;
}

짧고 이해하기 쉬운 한 줄짜리 정규식이 없습니다.

startsWith ()는 직설적입니다.

function startsWith($haystack, $needle) {
   return (strpos($haystack, $needle) === 0);
}

endsWith ()는 약간 공상적이고 느린 strrev ()를 사용합니다.

function endsWith($haystack, $needle) {
   return (strpos(strrev($haystack), strrev($needle)) === 0);
}

strrposstrpos 를 사용하여 start-with와 ends-with를 각각 검사 할 수 있습니다.

strrpos 를 사용하여 시작을 확인하고 strpos 를 사용하여 끝을 확인하면 끝까지 전체 문자열을 검사하는 대신 가능한 빨리 반환합니다. 또한이 솔루션은 임시 문자열을 생성하지 않습니다. downvoting하기 전에 이유를 설명하는 것을 고려하십시오. DWTF의 f-wit이이 함수의 작동 방식을 이해하지 못하거나 하나의 해결책 만 있다고 생각한다고해서이 해답이 잘못되었음을 의미하지는 않습니다.

function startsWith($haystack, $needle) {
    // search backwards starting from haystack length characters from the end
    return $needle === ''
      || strrpos($haystack, $needle, -strlen($haystack)) !== false;
}

function endsWith($haystack, $needle) {
    // search forward starting from end minus needle length characters
    if ($needle === '') {
        return true;
    }
    $diff = \strlen($haystack) - \strlen($needle);
    return $diff >= 0 && strpos($haystack, $needle, $diff) !== false;
}

테스트와 결과 ( 이것과 비교 ) :

startsWith('abcdef', 'ab') -> true
startsWith('abcdef', 'cd') -> false
startsWith('abcdef', 'ef') -> false
startsWith('abcdef', '') -> true
startsWith('', 'abcdef') -> false

endsWith('abcdef', 'ab') -> false
endsWith('abcdef', 'cd') -> false
endsWith('abcdef', 'ef') -> true
endsWith('abcdef', '') -> true
endsWith('', 'abcdef') -> false

주 : strncmp W substr_compare 함수는이 기능보다 성능이 우수합니다.


substr 함수는 많은 특수한 경우에 false 를 반환 할 수 있으므로 다음은 이러한 문제를 다루는 내 버전입니다.

function startsWith( $haystack, $needle ){
  return $needle === ''.substr( $haystack, 0, strlen( $needle )); // substr's false => empty string
}

function endsWith( $haystack, $needle ){
  $len = strlen( $needle );
  return $needle === ''.substr( $haystack, -$len, $len ); // ! len=0
}

테스트 ( true 좋은 의미) :

var_dump( startsWith('',''));
var_dump( startsWith('1',''));
var_dump(!startsWith('','1'));
var_dump( startsWith('1','1'));
var_dump( startsWith('1234','12'));
var_dump(!startsWith('1234','34'));
var_dump(!startsWith('12','1234'));
var_dump(!startsWith('34','1234'));
var_dump('---');
var_dump( endsWith('',''));
var_dump( endsWith('1',''));
var_dump(!endsWith('','1'));
var_dump( endsWith('1','1'));
var_dump(!endsWith('1234','12'));
var_dump( endsWith('1234','34'));
var_dump(!endsWith('12','1234'));
var_dump(!endsWith('34','1234'));

또한 substr_compare 함수도 살펴볼 가치가 있습니다. http://www.php.net/manual/en/function.substr-compare.php


나는 이것을 좋아할 것이다.

     function startWith($haystack,$needle){
              if(substr($haystack,0, strlen($needle))===$needle)
              return true;
        }

  function endWith($haystack,$needle){
              if(substr($haystack, -strlen($needle))===$needle)
              return true;
        }

또한 정규식을 사용할 수 있습니다.

function endsWith($haystack, $needle, $case=true) {
  return preg_match("/.*{$needle}$/" . (($case) ? "" : "i"), $haystack);
}

다음은 PHP 4를위한 효율적인 솔루션 substr_compare입니다 strcasecmp(substr(...)). PHP 5 대신에 를 사용하면 더 빠른 결과를 얻을 수 있습니다.

function stringBeginsWith($haystack, $beginning, $caseInsensitivity = false)
{
    if ($caseInsensitivity)
        return strncasecmp($haystack, $beginning, strlen($beginning)) === 0;
    else
        return strncmp($haystack, $beginning, strlen($beginning)) === 0;
}

function stringEndsWith($haystack, $ending, $caseInsensitivity = false)
{
    if ($caseInsensitivity)
        return strcasecmp(substr($haystack, strlen($haystack) - strlen($ending)), $haystack) === 0;
    else
        return strpos($haystack, $ending, strlen($haystack) - strlen($ending)) !== false;
}

이것이 사람들에게 왜 그렇게 어려운지 확실하지 않습니다. Substr은 훌륭한 작업을 수행하며 일치하지 않는 문자열 전체를 검색 할 필요가 없으므로 효율적입니다.

또한 정수 값을 검사하지는 않지만 문자열을 비교할 때 엄격한 걱정은 할 필요가 없습니다. 그러나, === 들어갈 좋은 습관입니다.

function startsWith($haystack,$needle) {
  substring($haystack,0,strlen($needle)) == $needle) { return true; }
   return false;
}

function endsWith($haystack,$needle) {
  if(substring($haystack,-strlen($needle)) == $needle) { return true; }
   return false;
}

또는 더 잘 최적화되었습니다.

function startsWith($haystack,$needle) {
  return substring($haystack,0,strlen($needle)) == $needle);
}

function endsWith($haystack,$needle) {
  return substring($haystack,-strlen($needle)) == $needle);
}

$ends_with = strrchr($text, '.'); // Ends with dot
$start_with = (0 === strpos($text, '.')); // Starts with dot

function startsWith($haystack, $needle)
{
     $length = strlen($needle);
     return (substr($haystack, 0, $length) === $needle);
}

function endsWith($haystack, $needle)
{
    $length = strlen($needle);
    if ($length == 0) {
        return true;
    }

    return (substr($haystack, -$length) === $needle);
}

정규식을 사용하지 않으려는 경우이 옵션을 사용하십시오.







string