문자열을 가져 와서 지정된 문자 / 문자열로 시작하거나 끝나는 경우 반환하는 두 가지 함수를 작성하는 방법은 무엇입니까?
예를 들면 다음과 같습니다.
$str = '|apples}';
echo startsWith($str, '|'); //Returns true
echo endsWith($str, '}'); //Returns true
답변
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);
}
정규식을 사용하지 않으려면 이것을 사용하십시오.
답변
substr_compare
시작과 끝을 확인 하는 기능을 사용할 수 있습니다 .
function startsWith($haystack, $needle) {
return substr_compare($haystack, $needle, 0, strlen($needle)) === 0;
}
function endsWith($haystack, $needle) {
return substr_compare($haystack, $needle, -strlen($needle)) === 0;
}
이것은 PHP 7에서 가장 빠른 솔루션 중 하나 여야합니다 ( 벤치 마크 스크립트 ). 8KB 건초 더미, 다양한 길이의 바늘 및 전체, 부분 및 일치 사례에 대해 테스트되었습니다. strncmp
로 시작하는 것이 더 빠르지 만 종료를 확인할 수는 없습니다.
답변
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
답변
모든 답은 지금까지 불필요한 작업의 부하를 수행하는 것, strlen calculations
, string allocations (substr)
, 등 'strpos'
및 'stripos'
기능의 첫 번째 항목의 인덱스 반환 $needle
에를 $haystack
:
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;
}
답변
function startsWith($haystack, $needle, $case = true) {
if ($case) {
return (strcmp(substr($haystack, 0, strlen($needle)), $needle) === 0);
}
return (strcasecmp(substr($haystack, 0, strlen($needle)), $needle) === 0);
}
function endsWith($haystack, $needle, $case = true) {
if ($case) {
return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)), $needle) === 0);
}
return (strcasecmp(substr($haystack, strlen($haystack) - strlen($needle)), $needle) === 0);
}
신용 :
답변
위의 정규식은 작동하지만 다른 조정 기능도 위와 같이 제안되었습니다.
function startsWith($needle, $haystack) {
return preg_match('/^' . preg_quote($needle, '/') . '/', $haystack);
}
function endsWith($needle, $haystack) {
return preg_match('/' . preg_quote($needle, '/') . '$/', $haystack);
}
답변
이 질문에는 이미 많은 답변이 있지만 어떤 경우에는 모든 것보다 간단한 것을 해결할 수 있습니다. 찾고있는 문자열이 알려진 경우 (하드 코드 된) 인용 부호없이 정규 표현식을 사용할 수 있습니다.
문자열이 ‘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()
하므로 위에 표시된 대로 함수 (예 :)를 정의 할 필요가 없습니다 .
그러나 다시 말하지만 이것은 모든 경우에 대한 해결책이 아니라 매우 구체적인 것입니다.
