PHP - स्ट्रिंग वर्णों पर पुनरावृति


120

वहाँ एक स्ट्रिंग के पात्रों पर पुनरावृति करने के लिए एक अच्छा तरीका है? मैं ऐसा करने में सक्षम होना चाहते हैं foreach, array_map, array_walk, array_filterएक स्ट्रिंग के पात्रों पर आदि।

टाइप कास्टिंग / करतब दिखाने के लिए मुझे कहीं भी नहीं मिला (पूरे स्ट्रिंग को ऐरे के एक तत्व के रूप में डालें), और मैंने जो सबसे अच्छा समाधान पाया है वह है कि ऐरे के निर्माण के लिए लूप का उपयोग करना। ऐसा लगता है कि कुछ बेहतर होना चाहिए। मेरा मतलब है, अगर आप इस पर अनुक्रमण कर सकते हैं तो क्या आपको इसे पुनरावृत्त करने में सक्षम नहीं होना चाहिए?

यह मेरे लिए सबसे अच्छा है

function stringToArray($s)
{
    $r = array();
    for($i=0; $i<strlen($s); $i++) 
         $r[$i] = $s[$i];
    return $r;
}

$s1 = "textasstringwoohoo";
$arr = stringToArray($s1); //$arr now has character array

$ascval = array_map('ord', $arr);  //so i can do stuff like this
$foreach ($arr as $curChar) {....}
$evenAsciiOnly = array_filter( function($x) {return ord($x) % 2 === 0;}, $arr);

वहाँ या तो है:

ए) स्ट्रिंग को चलने योग्य
बी बनाने का एक तरीका) स्ट्रिंग से चरित्र सरणी बनाने का एक बेहतर तरीका (और यदि ऐसा है, तो दूसरी दिशा के बारे में कैसे?)

मुझे लगता है कि यहाँ कुछ स्पष्ट याद आ रही है।


शायद आपको इस बारे में अधिक कहना चाहिए कि आप इसे पूरा करने की कोशिश कर रहे हैं ... ऐसा लगता है कि सामान्य स्ट्रिंग ऑपरेशन का उपयोग करने का एक बेहतर तरीका हो सकता है।
विनय पई

1
यहाँ एक वास्तविक उद्देश्य नहीं है। बस एक जिज्ञासा जिसके साथ मैं खेल रहा था। अजीब लग रहा था कि भले ही आप स्ट्रिंग्स पर अनुक्रमित कर सकते हैं आप इसे पुनरावृत्त नहीं कर सकते। मैं एक नुकसान पर भी था जब सार्थक उदाहरण का उपयोग करने के लिए सोचते हैं, लेकिन मैं अभी भी जानना चाहूंगा कि क्या किसी वर्ण सरणी का निर्माण किए बिना स्ट्रिंग्स वर्णों पर पुनरावृति करने के लिए कुछ तरीका है
jon_darkstar

हालांकि अच्छी बात है, जाहिर है मेरे उदाहरण बहुत उथले हैं। अर्थात - array_filterइस अर्थ में आप जो कुछ भी करेंगे, वह स्ट्रिंग या रेग-एक्स-फ़ंक्शंस के साथ बेहतर हो सकता है
jon_darkstar

Projecteuler.net/problem=20 को हल करना एक उदाहरण (हालांकि कुछ हद तक विवादित) उपयोग मामला हो सकता है।
निक एडवर्ड्स

एक नोट, के बारे में ($ i = 0; $ i <strlen ($ s); $ i ++) मैं लूपिंग से पहले एक चर में strlen ($ s) को संग्रहीत करूँगा, इस तरह से आप strlen () से अधिक कॉल नहीं करेंगे। 1 समय
अमीन

जवाबों:


176

चरण 1:str_split फ़ंक्शन का उपयोग करके स्ट्रिंग को सरणी में परिवर्तित करें

$array = str_split($your_string);

चरण 2: नए बने सरणी के माध्यम से लूप

foreach ($array as $char) {
 echo $char;
}

आप अधिक जानकारी के लिए PHP डॉक्स की जांच कर सकते हैं: str_split


हाह वाह। हाँ, यह है। और निश्चित रूप से निहित दूसरी दिशा कर सकता है। मैं इसे जल्द ही स्वीकार करूंगा जब तक कि कोई स्टिंग पर सही करने के लिए रास्ता नहीं दिखा सकता
jon_darkstar

@jon_darkstar मैं आपके आवेदन को नहीं जानता, लेकिन ध्यान दें कि किसी सरणी में प्रत्येक प्रविष्टि में एक महत्वपूर्ण ओवरहेड (4bytes IIRC) है। इसे छोड़ दें, यह 'काफी' तरीका है: nikic.github.com/2011/12/12/…
Daan Timmer

str_split() will split into bytes, rather than characters when dealing with a multi-byte encoded string.- तो str_splitयूनिकोड के साथ काम नहीं कर सकते
हैप्पी

85

सख्त स्ट्रिंग:

for ($i = 0; $i < strlen($str); $i++){
    echo $str[$i];
}

7
यह एक बेहतर उत्तर की तरह प्रतीत होता है क्योंकि यह प्रश्न का उत्तर देता है - यानी 'सरणी में कनवर्ट करें' के विपरीत एक स्ट्रिंग पर कैसे पुनरावृत्त किया जाए।
रॉबिन एंड्रयूज

2
जबरदस्त हंसी!!!!! सब कुछ @ उमरारिक यह उपलब्ध कराए गए उत्तर की तुलना में बहुत अधिक कुशल है।
0x476f72616e

5
बस ध्यान दें कि आप strlen()प्रत्येक पुनरावृत्ति पर कॉल कर रहे हैं । कोई भयानक बात नहीं है, क्योंकि PHP की लंबाई पहले से निर्धारित है, लेकिन फिर भी एक फ़ंक्शन कॉल है। यदि आपको गति की आवश्यकता है, तो लूप शुरू करने से पहले इसे एक चर में बेहतर रूप से सहेज लें।
विल्क्स- १-

2
यह मल्टीबाइट स्ट्रिंग्स के लिए अच्छा नहीं है, क्योंकि यहाँ हम बाइट ऑफसेट कर रहे हैं, प्रतीक नहीं
199

2
@OmarTariq "यह उत्तर है। दुनिया में क्या गलत है?" .... दुनिया के साथ गलत यह है कि दुनिया में अंग्रेजी की तुलना में अन्य भाषाएं हैं, यह फ़ंक्शन जैसा कि कहा गया है कि स्ट्रिंग में बाइट्स को पुनरावृति करेगा, पात्रों को नहीं।
एकाउंटेंट एनएपी

20

यदि आपके तार यूनिकोड में हैं तो आपको संशोधक के preg_splitसाथ उपयोग करना चाहिए/u

Php प्रलेखन में टिप्पणियों से:

function mb_str_split( $string ) { 
    # Split at all position not after the start: ^ 
    # and not before the end: $ 
    return preg_split('/(?<!^)(?!$)/u', $string ); 
} 

1
मल्टीबाइट स्ट्रिंग्स के लिए, mb_splitअधिक विश्वसनीय है।
इलेक्ट्रा

12

तुम भी एक सरणी की तरह $ s1 का उपयोग कर सकते हैं, अगर आपको केवल इसे एक्सेस करने की आवश्यकता है:

$s1 = "hello world";
echo $s1[0]; // -> h

6

@SeaBrightSystems उत्तर से विस्तारित, आप यह कोशिश कर सकते हैं:

$s1 = "textasstringwoohoo";
$arr = str_split($s1); //$arr now has character array

मैं असहमत हूं, यह जवाब मूल्य जोड़ता है, यह एक कार्यशील उदाहरण देता है कि str_split एक PHP एप्लिकेशन में कैसे काम कर सकता है। @SeaBrightSystems केवल दस्तावेज़ीकरण के लिए लिंक करता है, जो कभी-कभी इतना उपयोगी नहीं होता है जब कोई व्यक्ति यह देखने की कोशिश कर रहा है कि कोई फ़ंक्शन कैसे काम कर सकता है, एक उदाहरण दिया। अन्यथा ज्यादातर SO उत्तर सिर्फ php.net के लिंक होंगे
kurdtpage

6

उन लोगों के लिए जो php में स्ट्रिंग्स पर पुनरावृति करने का सबसे तेज़ तरीका खोज रहे हैं, Ive ने एक बेंचमार्क परीक्षण तैयार किया।
पहली विधि जिसमें आप कोष्ठक में अपनी स्थिति को निर्दिष्ट करके और एक सरणी की तरह स्ट्रिंग का इलाज करके सीधे स्ट्रिंग वर्णों तक पहुँचते हैं:

$string = "a sample string for testing";
$char = $string[4] // equals to m

मैंने खुद सोचा था कि उत्तरार्द्ध सबसे तेज़ तरीका है, लेकिन मैं गलत था।
दूसरी विधि के रूप में (जिसका उपयोग स्वीकृत उत्तर में किया जाता है):

$string = "a sample string for testing";
$string = str_split($string);
$char = $string[4] // equals to m

यह विधि तेजी से होने वाली है क्योंकि हम एक वास्तविक सरणी का उपयोग कर रहे हैं और किसी को एक सरणी नहीं मान रहे हैं।

उपरोक्त तरीकों में से प्रत्येक के लिए पिछली बार कॉल 1000000करने से इन बेंचमार्किंग परिणाम होते हैं:

स्ट्रिंग का उपयोग करना [i]
0.24960017204285 Seconds

Str_split का उपयोग करना
0.18720006942749 Seconds

जिसका अर्थ है दूसरी विधि तेजी से रास्ता है।


3

हम्म ... चीजों को जटिल करने की कोई जरूरत नहीं है। मूल बातें हमेशा महान काम करती हैं।

    $string = 'abcdef';
    $len = strlen( $string );
    $x = 0;

आगे की ओर:

while ( $len > $x ) echo $string[ $x++ ];

आउटपुट: abcdef

विपरीत दिशा:

while ( $len ) echo $string[ --$len ];

आउटपुट: fedcba


2
// Unicode Codepoint Escape Syntax in PHP 7.0
$str = "cat!\u{1F431}";

// IIFE (Immediately Invoked Function Expression) in PHP 7.0
$gen = (function(string $str) {
    for ($i = 0, $len = mb_strlen($str); $i < $len; ++$i) {
        yield mb_substr($str, $i, 1);
    }
})($str);

var_dump(
    true === $gen instanceof Traversable,
    // PHP 7.1
    true === is_iterable($gen)
);

foreach ($gen as $char) {
    echo $char, PHP_EOL;
}

मुझे आश्चर्य है कि इस उत्तर को केवल 1 उत्थान मिला :( यह यहाँ सबसे अधिक / केवल विश्वसनीय उत्तर है
लेखाकार

1

अधिकांश उत्तर गैर अंग्रेजी पात्रों के बारे में भूल गए !!!

strlenBYTES गिनता है, वर्ण नहीं, यही कारण है कि और यह सिबलिंग फ़ंक्शन अंग्रेजी वर्णों के साथ ठीक काम करता है, क्योंकि अंग्रेजी वर्ण UTF-8 और ASCII दोनों एन्कोडिंग में 1 बाइट में संग्रहीत होते हैं, आपको मल्टीबाइट स्ट्रिंग फ़ंक्शन का उपयोग करने की आवश्यकता होती है mb_*

इसमें एन्कोड किए गए किसी भी वर्ण के साथ काम होगाUTF-8

// 8 characters in 12 bytes
$string = "abcdأبتث";

$charsCount = mb_strlen($string, 'UTF-8');
for($i = 0; $i < $charsCount; $i++){
    $char = mb_substr($string, $i, 1, 'UTF-8');
    var_dump($char);
}

यह आउटपुट

string(1) "a"
string(1) "b"
string(1) "c"
string(1) "d"
string(2) "أ"
string(2) "ب"
string(2) "ت"
string(2) "ث"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.