length - php string variable




startsWith() e endsWith() funziona in PHP (20)

Estremità più veloceWith () soluzione:

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

Indice di riferimento:

# 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();

Risultati del benchmark:

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

Come posso scrivere due funzioni che prenderebbero una stringa e restituirebbero se inizia con il carattere / stringa specificato o finisce con esso?

Per esempio:

$str = '|apples}';

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

È possibile utilizzare strrpos e strpos per controllare rispettivamente start-with e ends-with.

Si noti che l'utilizzo di strrpos per il controllo inizia con e di strpos per il controllo termina con il ritorno al più presto possibile invece di controllare l'intera stringa fino alla fine. Inoltre, questa soluzione non crea una stringa temporanea. Considera di spiegare la ragione prima di fare downvoting. Solo perché un f-wit del DWTF non capisce come funzioni questa funzione o pensi che ci sia solo una soluzione non significa che questa risposta sia sbagliata.

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;
}

Test e risultati ( confronta con questo ):

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

Nota: le funzioni strncmp e substr_compare questa funzione.


Concentrandosi su startswith, se sei sicuro che le stringhe non siano vuote, aggiungendo un test sul primo carattere, prima del confronto, dello strlen, ecc., Accelera un po 'le cose:

function startswith5b($haystack, $needle) {
    return ($haystack{0}==$needle{0})?strncmp($haystack, $needle, strlen($needle)) === 0:FALSE;
}

È in qualche modo (20% -30%) più veloce. Aggiungere un altro char test, come $ haystack {1} === $ needle {1} non sembra accelerare molto le cose, potrebbe addirittura rallentare.

=== sembra più veloce di == operatore condizionale (a)?b:c sembra più veloce di if(a) b; else c; if(a) b; else c;

Per quelli che chiedono "perché non usare strpos?" chiamare altre soluzioni "lavoro non necessario"

strpos è veloce, ma non è lo strumento giusto per questo lavoro.

Per capire, ecco una piccola simulazione come esempio:

Search a12345678c inside bcdefga12345678xbbbbb.....bbbbba12345678c

Cosa fa "dentro" il computer?

    With strccmp, etc...

    is a===b? NO
    return false



    With strpos

    is a===b? NO -- iterating in haysack
    is a===c? NO
    is a===d? NO
    ....
    is a===g? NO
    is a===g? NO
    is a===a? YES
    is 1===1? YES -- iterating in needle
    is 2===3? YES
    is 4===4? YES
    ....
    is 8===8? YES
    is c===x? NO: oh God,
    is a===1? NO -- iterating in haysack again
    is a===2? NO
    is a===3? NO
    is a===4? NO
    ....
    is a===x? NO
    is a===b? NO
    is a===b? NO
    is a===b? NO
    is a===b? NO
    is a===b? NO
    is a===b? NO
    is a===b? NO
    ...
    ... may many times...
    ...
    is a===b? NO
    is a===a? YES -- iterating in needle again
    is 1===1? YES
    is 2===3? YES
    is 4===4? YES
    is 8===8? YES
    is c===c? YES YES YES I have found the same string! yay!
    was it at position 0? NOPE
    What you mean NO? So the string I found is useless? YEs.
    Damn.
    return false

Supponendo che strlen non iterazioni l'intera stringa (ma anche in quel caso) non è affatto conveniente.


Di solito finisco con una libreria come underscore-php questi giorni.

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   

La libreria è piena di altre utili funzioni.


La answer di è incredibilmente accurata, ma sfortunatamente il benchmark fornito ha una supervisione molto importante e dannosa.

Poiché ogni byte di aghi e pagliai è completamente casuale, la probabilità che una coppia ago-paglia mista differisca sul primo byte è 99.609375%, il che significa che, in media, circa 99609 delle 100000 coppie differiscono sul primo byte . In altre parole, il benchmark è fortemente sbilanciato verso l' startswith implementazioni che controllano esplicitamente il primo byte, come fa invece strncmp_startswith2 .

Se invece il ciclo di generazione del test è implementato come segue:

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 />";

i risultati del benchmark raccontano una storia leggermente diversa:

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

Ovviamente, questo benchmark potrebbe non essere perfettamente imparziale, ma mette alla prova l'efficienza degli algoritmi quando vengono forniti anche aghi parzialmente corrispondenti.


La funzione substr può restituire false in molti casi speciali, quindi ecco la mia versione, che tratta questi problemi:

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
}

Test ( true significa buono):

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'));

Inoltre, vale anche la funzione substr_compare . http://www.php.net/manual/en/function.substr-compare.php


Mi rendo conto che questo è stato completato, ma potresti voler dare un'occhiata a strncmp quanto ti permette di mettere la lunghezza della stringa da confrontare, quindi:

function startsWith($haystack, $needle, $case=true) {
    if ($case)
        return strncasecmp($haystack, $needle, strlen($needle)) == 0;
    else
        return strncmp($haystack, $needle, strlen($needle)) == 0;
}    

One-liner brevi e facili da capire senza espressioni regolari.

startsWith () è semplice.

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

endsWith () usa il leggermente elegante e lento strrev ():

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

Puoi usare strpos e strrpos

$bStartsWith = strpos($sHaystack, $sNeedle) == 0;
$bEndsWith = strrpos($sHaystack, $sNeedle) == strlen($sHaystack)-strlen($sNeedle);

Questa domanda ha già molte risposte, ma in alcuni casi puoi accontentarti di qualcosa di più semplice di tutti loro. Se la stringa che stai cercando è nota (codificata), puoi utilizzare espressioni regolari senza quotazioni, ecc.

Controlla se una stringa inizia con "ABC":

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

termina con 'ABC':

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

Nel mio caso semplice, volevo controllare se una stringa termina con una barra:

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

Il vantaggio: poiché è molto breve e semplice, non è necessario definire una funzione (come ad esempio endsWith() ) come mostrato sopra.

Ma ancora una volta - questa non è una soluzione per ogni caso, solo questo molto specifico.


Qui ci sono due funzioni che non introducono una stringa temporanea, che potrebbe essere utile quando gli aghi sono sostanzialmente grandi:

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

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

Se la velocità è importante per te, prova questo. (Credo che sia il metodo più veloce)

Funziona solo per le stringhe e se $ haystack è solo 1 carattere

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

Tutte le risposte sembrano fare un sacco di lavoro non necessario, strlen calculations , string allocations (substr) , ecc. Le 'strpos' e 'stripos' restituiscono l'indice della prima occorrenza di $needle in $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;
}

in breve:

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

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

Lo farei così

     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;
        }

Puoi anche usare le espressioni regolari:

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

Ecco una soluzione efficiente per PHP 4. Potresti ottenere risultati più veloci se su PHP 5 usando substr_compareinvece di strcasecmp(substr(...)).

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;
}

Molte delle risposte precedenti funzioneranno altrettanto bene. Tuttavia, questo è forse il più breve possibile e puoi farlo ciò che desideri. Dichiari solo che ti piacerebbe che fosse "restituito vero". Quindi ho incluso soluzioni che restituiscono booleano vero / falso e testuale vero / falso.

// boolean true/false
function startsWith($haystack, $needle)
{
    return strpos($haystack, $needle) === 0 ? 1 : 0;
}

function endsWith($haystack, $needle)
{
    return stripos($haystack, $needle) === 0 ? 1 : 0;
}


// textual true/false
function startsWith($haystack, $needle)
{
    return strpos($haystack, $needle) === 0 ? 'true' : 'false';
}

function endsWith($haystack, $needle)
{
    return stripos($haystack, $needle) === 0 ? 'true' : 'false';
}

$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);
}

Usalo se non vuoi usare un'espressione regolare.





string