शुरू होता है() और समाप्त होता है() PHP में फ़ंक्शन




string (20)

मैं दो फ़ंक्शंस कैसे लिख सकता हूं जो स्ट्रिंग लेते हैं और यदि यह निर्दिष्ट वर्ण / स्ट्रिंग या इसके साथ समाप्त होता है तो वापस लौटाता है?

उदाहरण के लिए:

$str = '|apples}';

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

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.2 9)

(सबसे तेज़ करने के लिए सबसे तेज़ क्रमबद्ध)

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


आप strrpos और strrpos उपयोग कर सकते हैं

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

इस प्रश्न में पहले से ही कई जवाब हैं, लेकिन कुछ मामलों में आप उन सभी की तुलना में कुछ आसान के लिए व्यवस्थित कर सकते हैं। यदि आप जिस स्ट्रिंग को ढूंढ रहे हैं उसे जाना जाता है (हार्डकोडेड), तो आप बिना किसी उद्धरण के नियमित अभिव्यक्ति का उपयोग कर सकते हैं।

जांचें कि एक स्ट्रिंग 'एबीसी' से शुरू होती है या नहीं:

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

'एबीसी' के साथ समाप्त होता है:

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

मेरे साधारण मामले में, मैं जांचना चाहता था कि एक स्ट्रिंग स्लैश के साथ समाप्त होती है या नहीं:

preg_match('/\/$/', $myPath);   // slash has to be quoted

लाभ: चूंकि यह बहुत छोटा और सरल है, इसलिए आपको ऊपर दिखाए गए फ़ंक्शन को परिभाषित करने की आवश्यकता नहीं है (जैसे endsWith() )।

लेकिन फिर - यह हर मामले के लिए एक समाधान नहीं है, बस यह बहुत विशिष्ट है।


का answer अविश्वसनीय रूप से गहन है, लेकिन दुर्भाग्यवश, प्रदान किए गए बेंचमार्क में एक बहुत ही महत्वपूर्ण और हानिकारक निरीक्षण है।

चूंकि सुइयों और घास के मैदानों में हर बाइट पूरी तरह से यादृच्छिक है, इसलिए संभावना है कि सुई-हैस्टैक जोड़ी पहले बाइट पर भिन्न होगी 99.60 9 375%, जिसका मतलब है कि औसतन, 100000 जोड़े के 9960 9 पहले बाइट पर अलग होंगे । दूसरे शब्दों में, बेंचमार्क startswith कार्यान्वयन की दिशा में भारी पक्षपातपूर्ण है जो पहले बाइट को स्पष्ट रूप से strncmp_startswith2 है, क्योंकि strncmp_startswith2 करता है।

यदि टेस्ट-जनरेटिंग लूप को इसके बजाए कार्यान्वित किया गया है:

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

बेशक, यह बेंचमार्क अभी भी पूरी तरह से निष्पक्ष नहीं हो सकता है, लेकिन आंशिक रूप से मेल खाने वाली सुइयों को दिए जाने पर यह एल्गोरिदम की दक्षता का परीक्षण करता है।


जेम्स ब्लैक के जवाब के आधार पर, यहां इसका अंत है संस्करण के साथ:

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

function endsWith($haystack, $needle, $case=true) {
     return startsWith(strrev($haystack),strrev($needle),$case);

}

नोट: मैंने ब्लैक ब्लैक के स्टार्ट के साथ अगर-दूसरे भाग को फ़ंक्शन के साथ बदल दिया है, क्योंकि strncasecmp वास्तव में strncmp का केस-असंवेदनशील संस्करण है।


निम्नलिखित क्यों नहीं?

//How to check if a string begins with another string
$haystack = "valuehaystack";
$needle = "value";
if (strpos($haystack, $needle) === 0){
    echo "Found " . $needle . " at the beginning of " . $haystack . "!";
}

आउटपुट:

Valuehaystack की शुरुआत में मूल्य मिला!

ध्यान रखें, अगर घास में सुई नहीं मिली तो strpos झूठ वापस आ जाएंगे, और अगर 0, और केवल तभी, सुई इंडेक्स 0 (एकेए शुरुआत) में पाया गया था।

और यहां समाप्त होता है:

$haystack = "valuehaystack";
$needle = "haystack";

//If index of the needle plus the length of the needle is the same length as the entire haystack.
if (strpos($haystack, $needle) + strlen($needle) === strlen($haystack)){
    echo "Found " . $needle . " at the end of " . $haystack . "!";
}

इस परिदृश्य में एक समारोह शुरू होने की आवश्यकता नहीं है () के रूप में

(strpos($stringToSearch, $doesItStartWithThis) === 0)

सही या गलत सही वापस आ जाएगा।

ऐसा लगता है कि यह अजीब लगता है कि यह जंगली कार्यों के साथ यहां इतना आसान है।


पिछले कई उत्तरों में भी काम करेगा। हालांकि, यह संभवतः छोटा है जितना आप इसे बना सकते हैं और जो भी आप चाहते हैं वह कर सकते हैं। आप बस बताते हैं कि आप इसे 'सत्य वापस' करना चाहते हैं। इसलिए मैंने ऐसे समाधान शामिल किए हैं जो बूलियन सत्य / झूठे और पाठ को सच / गलत लौटाते हैं।

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

बस एक सिफारिश:

function startsWith($haystack,$needle) {
    if(!$needle) return true;
    if($haystack[0]<>$needle[0]) return false;
    if(substr_compare($haystack,$needle,0,strlen($needle))==0) return true;
    return false;
}

तारों के पहले चरित्र की तुलना में, उस अतिरिक्त रेखा, झूठी मामला तुरंत लौट सकती है , इसलिए आपकी कई तुलनाओं को बहुत तेज बनाते हैं (7x तेज होने पर तेज़)। वास्तविक मामले में आप उस सिंगल लाइन के प्रदर्शन में लगभग कोई कीमत नहीं देते हैं, इसलिए मुझे लगता है कि इसमें शामिल है। (साथ ही, व्यावहारिक रूप से, जब आप एक विशिष्ट प्रारंभिक खंड के लिए कई तारों का परीक्षण करते हैं, तो अधिकांश तुलना एक सामान्य मामले में विफल हो जाएंगी क्योंकि आप कुछ ढूंढ रहे हैं।)


मुझे एहसास हुआ कि यह समाप्त हो गया है, लेकिन आप strncmp को देखना चाह सकते हैं क्योंकि यह आपको स्ट्रिंग की लंबाई को तुलना करने की अनुमति देता है, इसलिए:

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

मैं आमतौर पर इन दिनों 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   

पुस्तकालय अन्य आसान कार्यों से भरा है।


यदि आपके लिए गति महत्वपूर्ण है, तो इसे आजमाएं। (मुझे विश्वास है कि यह सबसे तेज़ तरीका है)

केवल तारों के लिए काम करता है और यदि $ हैस्टैक केवल 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

यह काम कर सकता है

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

स्रोत: https://.com/a/4419658


यहां दो फ़ंक्शन हैं जो एक अस्थायी स्ट्रिंग नहीं पेश करते हैं, जो उपयोगी हो सकती है जब सुई काफी बड़ी होती है:

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

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

यहां स्वीकृत उत्तर का बहु-बाइट सुरक्षित संस्करण है, यह यूटीएफ -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);
}

शुरुआत के साथ फ़ोकस करना, यदि आप सुनिश्चित हैं कि स्ट्रिंग खाली नहीं हैं, तुलना करने से पहले पहले चार पर एक परीक्षण जोड़ना, स्ट्रेल, आदि, चीजों को थोड़ा सा गति देता है:

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

यह किसी भी तरह (20% -30%) तेज है। एक और चार टेस्ट जोड़ना, जैसे कि $ हैस्टैक {1} === $ सुई {1} चीजों को तेज़ करने में प्रतीत नहीं होता है, यहां तक ​​कि धीमा भी हो सकता है।

=== == सशर्त ऑपरेटर (a)?b:c से तेज लगता है (a)?b:c if(a) b; else c; से तेज लगता है if(a) b; else c; if(a) b; else c;

उन लोगों के लिए "क्यों स्ट्रॉप्स का उपयोग नहीं करते?" अन्य समाधानों को बुलाकर "अनावश्यक काम"

स्ट्रॉप्स तेज़ है, लेकिन यह इस नौकरी के लिए सही उपकरण नहीं है।

समझने के लिए, यहां एक उदाहरण के रूप में थोड़ा सिमुलेशन है:

Search a12345678c inside bcdefga12345678xbbbbb.....bbbbba12345678c

कंप्यूटर "अंदर" क्या करता है?

    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

मान लें कि स्ट्रेलन पूरे स्ट्रिंग को फिर से नहीं चलाता है (लेकिन उस मामले में भी) यह बिल्कुल सुविधाजनक नहीं है।


संक्षेप में:

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

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

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


Not sure why this is so difficult for people. Substr does a great job and is efficient as you don't need to search the whole string if it doesn't match.

Additionally, since I'm not checking integer values but comparing strings I don't have to necessarily have to worry about the strict === case. However, === is a good habit to get into.

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

or even better optimized.

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

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

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

function endsWith($haystack, $needle)
{
    $length = strlen($needle);

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

अगर आप रेगेक्स का उपयोग नहीं करना चाहते हैं तो इसका इस्तेमाल करें।


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

क्रेडिट करने के लिए :

जांचें कि कोई स्ट्रिंग किसी अन्य स्ट्रिंग के साथ समाप्त होती है या नहीं

जांचें कि कोई स्ट्रिंग किसी अन्य स्ट्रिंग से शुरू होती है या नहीं





string