функции functionsWith () и окончание () в PHP - PullRequest
1349 голосов
/ 07 мая 2009

Как я могу написать две функции, которые будут принимать строку и возвращать ее, если она начинается с указанного символа / строки или заканчивается ею?

Например:

$str = '|apples}';

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

Ответы [ 30 ]

1450 голосов
/ 07 мая 2009
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);
}

Используйте это, если вы не хотите использовать регулярное выражение.

967 голосов
/ 06 мая 2012

Вы можете использовать функцию 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 ( тестовый скрипт ). Проверено на стогах сена 8 КБ, иголках различной длины и полных, частичных и несоответствующих случаях. strncmp на ощупь быстрее для начала, но не может проверять конец.

231 голосов
/ 24 августа 2011

Обновлено 23 августа 2016 года

Функции

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

133 голосов
/ 14 мая 2009

Похоже, что все ответы до сих пор выполняют ненужную работу, 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;
}
46 голосов
/ 07 мая 2009
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);
}

Кредит :

Проверить, заканчивается ли строка другой строкой

Проверить, начинается ли строка с другой строки

28 голосов
/ 19 июня 2009

Регулярное выражение действует выше, но с другими настройками, также предложенными выше:

 function startsWith($needle, $haystack) {
     return preg_match('/^' . preg_quote($needle, '/') . '/', $haystack);
 }

 function endsWith($needle, $haystack) {
     return preg_match('/' . preg_quote($needle, '/') . '$/', $haystack);
 }
23 голосов
/ 06 января 2016

На этот вопрос уже есть много ответов, но в некоторых случаях вы можете согласиться на что-то более простое, чем все они. Если искомая строка известна (жестко закодирована), вы можете использовать регулярные выражения без кавычек и т. Д.

Проверьте, начинается ли строка с '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()), как показано выше.

Но опять же - это не решение для каждого случая, только это очень конкретное.

22 голосов
/ 15 декабря 2009

Если скорость важна для вас, попробуйте это (я считаю, что это самый быстрый метод)

Работает только для строк, и если $ haystack только 1 символ

function startsWithChar($needle, $haystack)
{
   return ($needle[0] === $haystack);
}

function endsWithChar($needle, $haystack)
{
   return ($needle[strlen($needle) - 1] === $haystack);
}

$str='|apples}';
echo startsWithChar($str,'|'); //Returns true
echo endsWithChar($str,'}'); //Returns true
echo startsWithChar($str,'='); //Returns false
echo endsWithChar($str,'#'); //Returns false
17 голосов
/ 02 августа 2013

Вот две функции, которые не вводят временную строку, что может быть полезно, когда иглы существенно большие:

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

function endsWith($haystack, $needle)
{
    return $needle === '' || substr_compare($haystack, $needle, -strlen($needle)) === 0;
}
16 голосов
/ 17 сентября 2009

Я понимаю, что это было закончено, но вы можете посмотреть на strncmp , так как это позволяет указать длину строки для сравнения, поэтому:

function startsWith($haystack, $needle, $case=true) {
    if ($case)
        return strncasecmp($haystack, $needle, strlen($needle)) == 0;
    else
        return strncmp($haystack, $needle, strlen($needle)) == 0;
}    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...