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


1478

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

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

$str = '|apples}';

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

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

1
जैसा कि इस स्वसंपूर्ण पुस्तकालय में पाया गया है, आप इसे उपयोगी s($str)->startsWith('|')और s($str)->endsWith('}')उपयोगी मान सकते हैं
जौ

3
चेतावनी: अधिकांश उत्तर यहां बहु-बाइट एन्कोडिंग जैसे यूटीएफ -8 में अविश्वसनीय हैं।
अल्वारो गोंजालेज

मेरी उपरोक्त टिप्पणी के बाद, आप नवीनतम संस्करण (आज के अनुसार, 5.4 ) का उपयोग करना सुनिश्चित कर सकते हैं । विशेष रूप से, startWith () को बड़े हिस्टैक स्ट्रिंग्स के लिए अनुकूलित किया गया है।
ग्रास डबल

जवाबों:


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

यदि आप regex का उपयोग नहीं करना चाहते हैं तो इसका उपयोग करें।


16
+1 यह स्वीकृत उत्तर की तुलना में क्लीनर है। इसके अलावा, $lengthअंतिम पंक्ति में की जरूरत नहीं है endsWith()
बहुत ज्यादा php

13
मैं कहता हूं कि अंत में ('फू', '') == असत्य सही व्यवहार है। क्योंकि फू कुछ भी नहीं के साथ समाप्त नहीं होता है। 'फू' का अंत 'ओ', 'ऊ' और 'फू' से होता है।
मृ।

125
एंड्सविथ को बहुत छोटा लिखा जा सकता है:return substr($haystack, -strlen($needle))===$needle;
रोक

12
आप बच सकते हैं ifपारित करके पूरी तरह $lengthके लिए तीसरे पैरामीटर के रूप में substr: return (substr($haystack, -$length, $length);। यह $length == 0खाली स्ट्रिंग लौटाकर पूरे मामले को संभालता है $haystack
mxxk

20
@ मेरस मैं मल्टी-बाइट सुरक्षित कार्यों का उपयोग करने की सलाह दूंगा, जैसे mb_strlen और mb_substr
19Gerhard85

1024

आप उपयोग कर सकते हैं 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शुरू-साथ के लिए एक स्पर्श तेजी से है, लेकिन यह अंत के साथ जाँच नहीं कर सकता।


74
इस जवाब ने इसे डेली डब्ल्यूटीएफ को बना दिया! : D देखें thedailywtf.com/articles/…
Wim Ten Brink

कृपया ध्यान दें कि @DavidWallace और @FrancescoMM टिप्पणियां इस उत्तर के पुराने संस्करण पर लागू होती हैं। वर्तमान उत्तर का उपयोग करता है strrposजो (अगर) सुई तुरंत विफल हो जाती है यदि सुई धड़ल्ले की शुरुआत से मेल नहीं खाती है।
सलमान A

2
मुझे नहीं मिला। Php.net/manual/en/function.strrpos.php के आधार पर : "यदि मान ऋणात्मक है, तो इसके बजाय स्ट्रिंग के अंत से कई पात्रों से खोज शुरू होगी, पीछे की ओर खोज की जाएगी।" ऐसा लगता है कि हम चरित्र 0 से शुरू कर रहे हैं (क्योंकि -strlength($haystack)) और वहां से पिछड़े की खोज कर रहे हैं? इसका मतलब यह नहीं है कि आप कुछ भी नहीं खोज रहे हैं? मुझे भी इसके !== falseकुछ हिस्सों की समझ नहीं है । मैं अनुमान लगा रहा हूं कि यह PHP के एक क्विक पर निर्भर है जहां कुछ मूल्य "सत्य" और अन्य "मिथ्या" हैं, लेकिन इस मामले में यह कैसे काम करता है?
वेलबॉग

3
@Welbog: उदाहरण के लिए haystack = xxxyyyसुई = yyyऔर strrposखोज का उपयोग करना पहले से शुरू होता है x। अब हमारे यहाँ एक सफल मैच नहीं है (पाया गया y के बजाय x) और हम अब और पीछे नहीं जा सकते (हम स्ट्रिंग की शुरुआत में हैं) खोज तुरंत विफल हो जाती है । उपयोग करने के बारे में !== false- strrposउपरोक्त उदाहरण में 0 या गलत वापस आएगा और अन्य मूल्य नहीं। इसी तरह, strposउपरोक्त उदाहरण में $temp(अपेक्षित स्थिति) या गलत वापसी कर सकते हैं । मैं साथ चला गया !== falseस्थिरता के लिए, लेकिन आप इस्तेमाल कर सकते हैं === 0और === $tempक्रमश: कार्यों में।
सलमान ए

8
@spoo यह पहले से ही स्थापित किया गया है कि स्ट्रैप === 0 एक भयानक समाधान है यदि हैस्टैक बड़ा है और सुई मौजूद नहीं है।
सलमान ए

243

अपडेटेड 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


3
यदि तार खाली नहीं हैं, जैसा कि आपके परीक्षणों में है, यह वास्तव में किसी तरह (20-30%) तेज है: function startswith5b($haystack, $needle) {return ($haystack{0}==$needle{0})?strncmp($haystack, $needle, strlen($needle)) === 0:FALSE;}मैंने नीचे एक उत्तर जोड़ा।
फ्रांसेस्कोएम

3
@Jronny 110 क्योंकि 133 से कम है ... ??
mpen

2
डार, मुझे नहीं पता कि उस समय मेरे सिर में क्या हुआ था। नींद की कमी।
3

1
@mpen, मैंने देखा कि हाथी बिल्कुल भी नहीं है :(
विस्मान

1
प्रदर्शन के परीक्षण में ये परीक्षण अच्छे नहीं हैं। आप जो कर रहे हैं वह सुई के रूप में यादृच्छिक स्ट्रिंग का उपयोग कर रहा है। 99.99% मामलों में कोई मैच नहीं होगा। पहले बाइट के मिलान के बाद अधिकांश कार्य समाप्त हो जाएंगे। जब एक मैच पाया जाता है तो मामलों के बारे में क्या? सफल मैच के समापन में किस फ़ंक्शन में कम से कम समय लगता है? उन मामलों के बारे में जहां 99% सुई से मेल खाते हैं लेकिन पिछले कुछ बाइट्स नहीं हैं? कोई भी मैच समाप्त होने में किस फ़ंक्शन को कम से कम समय लगता है?
सलमान एक

137

सभी जवाब अब तक अनावश्यक काम का भार क्या करने लगते हैं, 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;
}

2
endsWith()फ़ंक्शन में त्रुटि है। इसकी पहली पंक्ति (-1 के बिना) होनी चाहिए: $expectedPosition = strlen($haystack) - strlen($needle);
एनरिको डेटोमा

6
स्ट्रलेन () चीज अनावश्यक नहीं है। यदि स्ट्रिंग दी गई सुई से शुरू नहीं होती है, तो उर कोड अनावश्यक रूप से पूरे हिस्टैक को स्कैन करेगा।
AppleGrew

5
@ मार्का येया, बस शुरुआत की जाँच बहुत तेजी से होती है, खासकर यदि आप कुछ ऐसा कर रहे हैं जैसे कि MIME प्रकार (या किसी अन्य स्थान पर जहां स्ट्रिंग बड़ी हो) की जाँच कर रहे हैं
chacham15

2
@ मैं 1000 चरखा और 10 या 800 चार सूई के साथ कुछ बेंचमार्क करता था और स्ट्रैप 30% तेज था। यह
बताने

7
आपको सुई को उद्धृत करने पर दृढ़ता से विचार करना चाहिए जैसे strpos($haystack, "$needle", 0)कि कोई भी मौका हो यह पहले से ही एक स्ट्रिंग नहीं है (जैसे, अगर यह आ रहा है json_decode())। अन्यथा, [विषम] डिफ़ॉल्ट व्यवहार strpos()अप्रत्याशित परिणाम पैदा कर सकता है: " यदि सुई एक स्ट्रिंग नहीं है, तो इसे एक पूर्णांक में बदल दिया जाता है और एक चरित्र के क्रमिक मूल्य के रूप में लागू किया जाता है। "
शांत

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

इसका श्रेय :

जांचें कि क्या एक स्ट्रिंग दूसरे स्ट्रिंग के साथ समाप्त होती है

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


1
strtolower केस असंवेदनशील कार्य करने का सबसे अच्छा तरीका नहीं है। कुछ स्थानों में आवरण केवल ऊपरी और निचले की तुलना में अधिक जटिल है।
सैंडर रिजकेन

8
मैं शिकायत करता हूं और कोई समाधान नहीं देखता ... यदि आप कह रहे हैं कि यह बुरा है, तो आपको एक उदाहरण देना चाहिए कि यह कैसा होना चाहिए।
KdgDev

2
@WebDevHobo: यही कारण है कि मैंने आपकी टिप्पणी से एक दिन पहले खुद एक उत्तर जोड़ा है। अपने कोड के लिए strcasecmp वास्तव में सही काम था।
सैंडर रिजेकेन

29

रेगेक्स ऊपर कार्य करता है, लेकिन अन्य ट्विक्स के साथ भी ऊपर सुझाव दिया गया है:

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

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

2
स्ट्रिंग ऑपरेशन के लिए php में पैरामीटर्स का ऑर्डर $ haystack, $ सुई है। ये फ़ंक्शन पीछे की ओर हैं और सरणी फ़ंक्शन की तरह कार्य करते हैं जहां ऑर्डर वास्तव में $ सुई, $ हेस्टैक है।
एंडी

29

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

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

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

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

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

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

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

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

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


आपको स्ट्रिंग को हार्ड कोड करने की आवश्यकता नहीं है। रेगेक्स गतिशील हो सकता है।
रयान

2
@ स्वयं सच है, लेकिन यदि स्ट्रिंग हार्डकोड नहीं है, तो आपको इसे बचाना होगा। इस सवाल पर वर्तमान में 2 उत्तर हैं जो इसे करते हैं। यह आसान है, लेकिन यह कोड को थोड़ा जटिल करता है। तो मेरा कहना यह था कि बहुत सरल मामलों के लिए, जहाँ हार्डकोडिंग संभव है, आप इसे सरल रख सकते हैं।
दोपहर १५'१६

1
आपको स्लैश से बचना भी नहीं है, आप रेगेक्स को किसी अन्य पात्र में लपेट सकते हैं, जैसे @, ताकि स्लैश ( /) को बचना न पड़े। उदाहरण # 3 यहाँ देखें: php.net/manual/en/function.preg-match.php
cjbarth

धन्यवाद @cjbarth मेरे हिसाब से अपना जवाब बदल दिया। BTW, "#" एक स्लैश से निपटने के दौरान php.net/manual/en/regexp.reference.delimiters.php में दिया गया उदाहरण है ।
noamtm

23

यदि गति आपके लिए महत्वपूर्ण है, तो यह प्रयास करें। (मेरा मानना ​​है कि यह सबसे तेज़ विधि है)

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

1
यह शायद सबसे कुशल उत्तर है क्योंकि किसी भी फ़ंक्शन को अतिरिक्त, बस सामान्य स्ट्रिंग के रूप में उपयोग नहीं करना ...

यदि स्ट्रिंग में कम से कम एक वर्ण है और दो मापदंडों की अदला
a1an

1
रचनात्मक। सुइयां जिनमें हिस्टैक्स होते हैं। BTW वहाँ के साथ कुछ बदसूरत waning है: endsWithChar('','x')लेकिन परिणाम सही है
Tino

18

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

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

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

2
PHP5.1 और IMHO सबसे अच्छा जवाब के बाद से +1 काम करता है। परंतुendsWidth करना चाहिए return $needle==='' || substr_compare(... तो यह उम्मीद के -strlen($needle)===0मुताबिक काम करता है, जो बिना तय किए, endsWith('a','')वापसी करता हैfalse
टिनो

@Tino धन्यवाद ... मुझे लगता है कि यह substr_compare()वास्तव में एक बग है , इसलिए मैंने इसे ठीक करने के लिए एक पीआर जोड़ा है :)
Ja Febck

3
कॉल endsWith('', 'foo')एक चेतावनी को ट्रिगर करता है: "root_compare (): प्रारंभ स्थिति प्रारंभिक स्ट्रिंग लंबाई से अधिक नहीं हो सकती"। हो सकता है कि यह एक और बग है substr_compare(), लेकिन इससे बचने के लिए, आपको पूर्व जांच की तरह ...|| (strlen($needle) <= strlen($haystack) && substr_compare( ...) === 0);
gx_

@gx_ अधिक कोड के साथ मंदी की आवश्यकता नहीं है। बस उपयोग return $needle === '' || @substr_compare(.. इस चेतावनी को दबाने के लिए।
तिनो

17

सबसे तेज़ सिरों के साथ () समाधान:

# 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

3
अलग-अलग समाधानों की तुलना करने के लिए समय लेने और उन्हें वास्तव में बेंचमार्क करने के लिए +1! आपको यह भी उल्लेख करना चाहिए कि PHP का कौन सा संस्करण इस्तेमाल किया गया था, क्योंकि भाषा के विकसित होते ही अनुकूलन किया जाता है! मैंने एक PHP संस्करण से दूसरे PHP संस्करण में स्ट्रिंग तुलनात्मक कार्यों पर नाटकीय सुधार देखा है :)
क्रिस्टोफ 13

1
@ChristopheDeliens की गूंज और PHP संस्करण प्रदान करने का उनका अनुरोध। मैंने 7.3.2 पर आपका परीक्षण चलाया और इसी तरह के परिणाम FWIW मिले।
जेफ

16

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

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

आप इस के साथ कैसे करेंगे?
मपेन

@ मर्क - आप स्वीकृत उत्तर को देख सकते हैं, लेकिन मैं मुख्य रूप से strncmp का उपयोग करना पसंद करता हूं क्योंकि मुझे लगता है कि यह अधिक सुरक्षित है।
जेम्स ब्लैक

मेरा मतलब है विशेष रूप से strncmp के साथ। आप एक ऑफसेट निर्दिष्ट नहीं कर सकते। इसका मतलब यह होगा कि आपके एंडवाइस फ़ंक्शन को पूरी तरह से एक अलग विधि का उपयोग करना होगा।
एमपीएन

@Mark - सिरों के लिए मैं सिर्फ स्ट्रैप ( php.net/manual/en/function.strrpos.php ) का उपयोग करूंगा , लेकिन, आम तौर पर, कभी-कभी आप स्ट्रैम्प स्ट्रेंप का उपयोग करने के लिए जाते हैं, शायद एक सुरक्षित विकल्प है।
जेम्स ब्लैक

11

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

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

1
आप यहाँ ट्रिपल समतुल्य का उपयोग करके किया जाना चाहिए strpos($sHaystack, $sNeedle) == 0इस तरह strpos($sHaystack, $sNeedle) === 0? जब मैं false == 0मूल्यांकन करता हूं तो मुझे एक बग दिखाई देता है true
कल्याण

11

यहां स्वीकृत उत्तर का एक बहु-बाइट सुरक्षित संस्करण है, यह UTF-8 स्ट्रिंग्स के लिए ठीक काम करता है:

function startsWith($haystack, $needle)
{
    $length = mb_strlen($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);
}

2
im बहुत यकीन है कि यह सिर्फ CPU की बर्बादी है। StarstWith और EndsWith के लिए आपको बस चेक करने की जरूरत है, कि बाइट्स मैच हो रहा है, और यह वही है जो स्वीकृत उत्तर दे रहा है। यह 1 बार सुई के utf8 वर्णों की संख्या की गणना करने में समय बर्बाद करता है, और जहां n n की utf8 वर्णिका की स्थिति है .. मुझे लगता है कि 100% निश्चित होने के बिना, यह सिर्फ सीपीयू की बर्बादी है। क्या आप एक वास्तविक परीक्षण मामले के साथ आ सकते हैं जहाँ स्वीकृत उत्तर विफल रहता है, और यह नहीं है?
हैंश्रिकेन

2
@hanshenrik - यह btw हो सकता है, बहुत ही दुर्लभ मामले में जब आप एक स्ट्रिंग की तलाश करते हैं जिसमें UTF8 के समान बाइट्स होते हैं, लेकिन अंतिम चरित्र के आधे गायब होते हैं। जैसे, आपके पास यूनिकोड C5 91 (अक्षर ")") है और आप C5 की तलाश करते हैं (पत्र "shouldn't") यह आपको मैच नहीं देना चाहिए। दूसरी ओर, निश्चित रूप से, आप एक गैर-यूटीएफ सुई के लिए एक यूटीएफ की खोज क्यों करेंगे ... लेकिन बुलेटप्रूफ जांच के लिए, इसे एक संभावना माना जाना चाहिए।
dkellner

इसमें startsWithहोना चाहिए$length = mb_strlen($needle, 'UTF-8');
थॉमस केकेसेन

2
@ThomasKekeisen धन्यवाद, इसे ठीक किया।
वाहिद अमीरी

8

नियमित अभिव्यक्तियों के बिना एक-लाइनर्स को छोटा और आसानी से समझने वाला।

प्रारंभ () सीधे आगे है।

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

समाप्त होता है () थोड़े से फैंसी और धीमी स्ट्रिव का उपयोग करता है ():

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

@FrancescoMM: स्ट्रैप "सही टूल" नहीं है ... क्यों? फिर "सही उपकरण" क्या हैं? संपादित करें: मैंने आपका उत्तर नीचे पढ़ा है। मुझे लगा कि प्रोग्रामिंग आपके पास मौजूद संसाधनों का उपयोग करते हुए आविष्कार की तरह है .. इसलिए कोई सही या गलत नहीं है ... केवल काम कर रहा है या काम नहीं कर रहा है ... प्रदर्शन माध्यमिक है।
Fr0zenFyr

"क्योंकि यह खोज के लिए एक उपकरण है, तुलना के लिए नहीं?" सीआईटी। अरिस्टोटेल्स
फ्रांसेस्कोएम

7

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

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

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

===कंडेनसर == ऑपरेटर की (a)?b: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

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


यदि पहले अक्षर अलग हैं तो केवल एक गति है।
जाक

2
@ जेक हां, निश्चित रूप से, विचार यह है कि सांख्यिकीय रूप से ऐसा होता है, इसलिए स्पीडअप सामान्य रूप से पूरे परीक्षण सेट पर 20% -30% है (ऐसे मामलों में जहां यह अलग नहीं है)। जब आप अलग और ढीले होते हैं तो बहुत फायदा होता है जब वे नहीं होते हैं। औसत में आप 30% प्राप्त करते हैं (सेट के आधार पर भिन्न होता है, लेकिन ज्यादातर आप बड़े परीक्षणों पर गति प्राप्त करते हैं)
फ्रांसेस्कोएमएम

"लेकिन यह इस काम के लिए सही उपकरण नहीं है" ... कोई उद्धरण?
Fr0zenFyr

1
WTF। मैंने नीचे दी गई सभी प्रक्रिया को सूचीबद्ध किया है कि मुझे किसका हवाला देना चाहिए, इससे अधिक? क्या आप एक फ़ंक्शन का उपयोग करेंगे जो आपको यह बताने के लिए एक स्ट्रिंग के अंत तक खोजता है कि मुट्ठी चरित्र एक 'ए' नहीं है? इसकी परवाह किसे है? यह सही उपकरण नहीं है क्योंकि यह खोज के लिए एक उपकरण है, तुलना करने के लिए नहीं है, स्पष्ट रूप से बताने के लिए एरिस्टोटेल्स का हवाला देने की आवश्यकता नहीं है!
फ्रांसेस्कोएम

6

मुझे उम्मीद है कि नीचे उत्तर कुशल और सरल भी हो सकता है:

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

6

मैं आमतौर पर इन दिनों अंडरस्कोर-पीएचपी जैसी लाइब्रेरी के साथ जा रहा हूं ।

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   

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


6

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

क्योंकि सुइयों और haystacks में हर बाइट पूरी तरह से यादृच्छिक है, एक सुई- haystack जोड़ी की संभावना बहुत पहले बाइट पर अलग होगी 99.609375%, जिसका अर्थ है कि, 100000 जोड़े के लगभग 99609 पहले बाइट पर अलग-अलग होंगे । दूसरे शब्दों में, बेंचमार्क startswithकार्यान्वयन के प्रति भारी पक्षपाती है जो पहले बाइट को स्पष्ट रूप से जांचता है, जैसा कि 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

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


5

संक्षेप में:

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

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

5

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

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

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


2
अपने कोड में बग: startsWith("123", "0")देता हैtrue
Tino

हाँ, बुरा! $ जाँच हुई। माफ़ करना! (बस लाइन 3 में अवधारणा को चित्रित करना चाहता था)
डेकेलनर

4

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



4

मैं इसे इस तरह से करूंगा

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

अगर यह मेल नहीं खाता है तो झूठे को भूल जाना। गलत है, क्योंकि किसी फ़ंक्शन का रिटर्न वैल्यू 'ग्रहण' नहीं होना चाहिए, लेकिन मुझे पता है कि आप अन्य उत्तरों की तुलना में कम से कम बाद में क्या कर रहे हैं।
19

3

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

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

}

नोट: मैंने जेम्स ब्लैक के शुरुआती कार्य के लिए if-else पार्ट को स्वैप किया है, क्योंकि strncasecmp वास्तव में strncmp का केस-असंवेदनशील संस्करण है।


2
ध्यान दें कि strrev()है रचनात्मक लेकिन बहुत महंगा है, खासकर अगर आप कहते हैं के तार है ... 100Kb।
एलेक्सिस विल्के

सुनिश्चित करने के ===बजाय उपयोग ==करें। 0PHP में बहुत सी चीजों के बराबर है।
नवफाल

3

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

//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)

सही या गलत लौटेगा।

यह अजीब लगता है कि यह यहाँ चल रहे सभी जंगली कार्यों के साथ सरल है।


3
अजीब लगता है कि अगर आप स्ट्रिंग के अंदर "xy" की खोज कर रहे हैं, तो "abcdefghijklmxyz" के बजाय "x" की "a" से तुलना करें और FALSE को लौटाएं, तो आप हर वर्ण को "a" से "m" तक ढूंढते हैं, फिर "xy" को ढूंढते हैं स्ट्रिंग के अंदर, और अंत में आप FALSE लौटाते हैं क्योंकि इसकी स्थिति शून्य नहीं है! यह वही है जो आप कर रहे हैं, और यह किसी भी अन्य बड़े समारोह की तुलना में अजीब और जंगल है।
फ्रांसेस्कोएम

सरलता टाइपिंग में है, तर्क में नहीं।
केड हाफेन

यह इतना तर्क नहीं है, यह संभव अनुकूलन है जिसे फ्रांसेस्को इंगित कर रहा था। strpos()जब यह मेल खाता है तब सिवाय इसके उपयोग धीमा होगा। strncmp()इस मामले में बहुत बेहतर होगा।
एलेक्सिस विलके

जब आप इस तरह के निम्न स्तर के कार्य कर रहे होते हैं, तो आप आम तौर पर सबसे अधिक गति-अनुकूलित समाधान के लिए जाना चाहते हैं, चाहे कितना भी जटिल हो, क्योंकि यह लाखों बार कहा जाएगा। आपके द्वारा यहां प्राप्त या खो जाने वाले प्रत्येक माइक्रोसेकंड में बहुत वास्तविक अंतर होगा। तो बेहतर यह है कि नरक से बाहर की ओर मुड़ें (और फिर जटिलता के बारे में भूल जाएं, अब आपके पास फ़ंक्शन है), लुक के लिए जाने के बजाय और बाद में डरावनी राशि खो दें जब आपको पता भी न चले कि क्या गलत हुआ है। एक 2GB स्ट्रिंग की जाँच करने की कल्पना करें जो मेल नहीं खाती है।
dkellner

3

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

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

सच। हालांकि, पीटर एक फ़ंक्शन के लिए पूछ रहा था जो चरित्र के तार के साथ काम करेगा। बहरहाल, मैंने आपको तुष्ट करने के लिए अपना जवाब अपडेट कर दिया है।
21

अपने समाधान को संपादित करने के बाद अब पूरी तरह से अप्रचलित है। यह लौटता है 'true'और 'false'तार के रूप में, जो दोनों trueबूलियन अर्थों में हैं। यह कुछ हद तक underhanded.xcott.com की तरह एक अच्छा पैटर्न है ;)
टीनो

खैर, पीटर ने कहा कि वह चाहता था कि वह 'सच' लौटाए। इसलिए मुझे लगा कि वह जो मांगेगा, मैं उसे लौटा दूंगा। मैंने दोनों संस्करणों को जोड़ा है, बस उस स्थिति में जो वह नहीं चाहता था।
13

2

आप भी नियमित अभिव्यक्ति का उपयोग कर सकते हैं:

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

3
$ सुई के साथ बच जाना चाहिए preg_quote($needle, '/')
तैमो तिजहोफ

2

नो-कॉपी और नो-इंटर्न-लूप:

function startsWith(string $string, string $start): bool
{
    return strrpos($string, $start, - strlen($string)) !== false;
}

function endsWith(string $string, string $end): bool
{
    return ($offset = strlen($string) - strlen($end)) >= 0 
    && strpos($string, $end, $offset) !== false;
}

यह MrHus के कार्यान्वयन की तुलना में बहुत तेज़ होना चाहिए! मैं इसे बेंचमार्क कर सकता
हूं

1

यहाँ PHP 4 के लिए एक कुशल समाधान है। यदि आप substr_compareइसके बजाय PHP 5 का उपयोग करके तेजी से परिणाम प्राप्त कर सकते हैं 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;
}

0

आप इसके लिए fnmatch फ़ंक्शन का उपयोग कर सकते हैं ।

// Starts with.
fnmatch('prefix*', $haystack);
// Ends with.
fnmatch('*suffix', $haystack);

चेतावनी, नहीं द्विआधारी सुरक्षित, और यहां तक कि वाइल्डकार्ड युक्त = / सुइयों के खिलाफ सुरक्षित नहीं
hanshenrik
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.