পিএইচপি-র প্রতিটি স্ট্রিংয়ের উপর স্ট্রিংয়ের মাধ্যমে ইটারেট করুন


130

আমার একটি ফর্ম রয়েছে যা ব্যবহারকারীকে হয় একটি পাঠ্য ফাইল আপলোড করতে বা ফাইলের বিষয়বস্তু অনুলিপি / টেক্সারিয়াতে পেস্ট করতে দেয়। আমি সহজেই দুজনের মধ্যে পার্থক্য করতে পারি এবং যে কোনও একটিতে তারা স্ট্রিং ভেরিয়েবলের মধ্যে প্রবেশ করতে পারি তবে আমি সেখান থেকে কোথায় যাব?

আমার স্ট্রিংয়ের প্রতিটি লাইনটি পুনরাবৃত্তি করতে হবে (বিশেষত বিভিন্ন মেশিনে নিউলাইনগুলি সম্পর্কে চিন্তা না করা), এটি নিশ্চিত করে নিন যে এতে ঠিক একটি টোকেন রয়েছে (কোনও স্পেস, ট্যাব, কমা, ইত্যাদি) নেই, ডেটা স্যানিটাইজ করে তারপরে একটি এসকিউএল কোয়েরি উত্পন্ন করবে সমস্ত লাইন বন্ধ ভিত্তিক।

আমি মোটামুটি ভাল প্রোগ্রামার, তাই এটি কীভাবে করা যায় সে সম্পর্কে আমি সাধারণ ধারণা জানি, তবে পিএইচপি নিয়ে কাজ করার পরে এত দিন হয়ে গেছে যে আমি অনুভব করি যে আমি ভুল জিনিসগুলি অনুসন্ধান করছি এবং এইভাবে অকেজো তথ্য নিয়ে আসছি। আমার যে মুখ্য সমস্যাটি হচ্ছে তা হ'ল আমি স্ট্রিংয়ের লাইন বাই লাইনের সামগ্রীগুলি পড়তে চাই। এটি যদি ফাইল হয় তবে এটি সহজ ছিল।

আমি বেশিরভাগ দরকারী পিএইচপি ফাংশন খুঁজছি, এটি কীভাবে করা যায় তার জন্য অ্যালগরিদম নয়। কোনও পরামর্শ?


আপনি প্রথমে নতুন লাইনগুলি স্বাভাবিক করতে চাইতে পারেন। পদ্ধতিটি s($myString)->normalizeLineEndings()পাওয়া যায় github.com/delight-im/PHP-Str (এমআইটি লাইসেন্সের অধীনে গ্রন্থাগার) যার সাথে প্রচুর অন্যান্য দরকারী স্ট্রিং সহায়ক রয়েছে। আপনি সোর্স কোডটি একবার দেখে নিতে পারেন।
কাওয়

উত্তর:


190

preg_split পাঠ্যটি সহ ভেরিয়েবল, এবং প্রত্যাবর্তিত অ্যারেটিতে পুনরাবৃত্তি হবে:

foreach(preg_split("/((\r?\n)|(\r\n?))/", $subject) as $line){
    // do stuff with $line
} 

এই হ্যান্ডেলটি কি ^ n \ r এর সাথে যুক্ত হবে?
তোফার ফ্যাঙ্গিও

আমি নিশ্চিত নই যে আসকি ক্যারিজের রিটার্ন একবার ভেরিয়েবলের ভিতরে রাখলে \ r তে রূপান্তরিত হয়। যদি না হয় আপনি তার পরিবর্তে সর্বদা ascii মান সহ একটি বিভাজন () / এক্সপ্লোপ () ব্যবহার করতে পারেন - চি (13)
কিরিল

12
একটি ভাল regexp হয় /((\r?\n)|(\r\n?))/
ফলিক্স সাপরেলি

3
ইউনিক্স এলএফ (\ n), ম্যাকোস <9 সিআর (\ r), উইন্ডোজ সিআর + এলএফ (\ r \ n) এবং বিরল এলএফ + সিআর (\ n \ r) এর সাথে মিল রাখতে এটি হওয়া উচিত:/((\r?\n)|(\n?\r))/
দেবের জন্য অপেক্ষা করা ...

2
মাল্টি-বাইট ডেটার জন্য এটি বিপর্যয়করভাবে বোমা ফেলার সম্ভাবনা রয়েছে।
পিগার্ডিরিও

158

আমি বরং একটি উল্লেখযোগ্যভাবে দ্রুত (এবং মেমরি দক্ষ) বিকল্প প্রস্তাব করতে চাই : strtokবরং preg_split

$separator = "\r\n";
$line = strtok($subject, $separator);

while ($line !== false) {
    # do something with $line
    $line = strtok( $separator );
}

পারফরম্যান্স পরীক্ষা করে, আমি ১ test হাজার লাইন দিয়ে একটি পরীক্ষার ফাইলে 100 বার পুনরাবৃত্তি করেছি: preg_split27.7 সেকেন্ড সময় নিয়েছে, যেখানে strtok1.4 সেকেন্ড সময় নিয়েছে।

নোট করুন যদিও $separatorহিসাবে সংজ্ঞায়িত করা হয়েছে "\r\n", strtokউভয় চরিত্রের উপর পৃথক হবে - এবং PHP4.1.0 হিসাবে, খালি লাইন / টোকেনগুলি এড়িয়ে যান।

স্ট্রিটোক ম্যানুয়াল এন্ট্রিটি দেখুন: http://php.net/strtok


21
বড় লাইন সেটগুলি নিয়ে কাজ করার সময় পারফরম্যান্স বিবেচনার জন্য +1
কোডআঙ্গারি

4
যদিও এই ফাংশনটি এপিআই মোট জগাখিচুড়ি (বিভিন্ন পরামিতি সহ কল ​​করুন) এটি সেরা সমাধান। আমরাও prey_splitনা explodeকাঠামোবদ্ধ স্ট্রিং টুকরা ফলনশীল জন্য ব্যবহার করা উচিত। এটি বাজুকা দিয়ে উড়তে লক্ষ্য করার মতো ।
ম্যাকিয়েজ এসজেড

1
অ্যাপটি চলাকালীন আপনি যদি মেমরির ব্যবহারটি পরীক্ষা করেন তবে আপনি যাদুটি দেখতে পাবেন। আপনি যখন প্রতিটি লাইনের মধ্য দিয়ে লুপ করেন সে ক্ষেত্রে এটি মেমোরিতে পড়তে থাকা ফাইলটিকে আসলে টান দেয় এবং এটি আপনার টোকেনের অবস্থানটি রাখে। সত্যিকারের স্মৃতিশক্তি দক্ষ হওয়ার জন্য আপনি এটি ফ্লাশ করতে চাইবেন। php.net/strtok#103051
AbsoluteƵERØ

2
দ্রুত দ্রষ্টব্য, lo লুপের strtok()ভিতরে অন্য কোনও কিছু ব্যবহার করা whileজিনিসগুলিকে ভেঙে দেবে। আমিও প্রথম স্থান (একটি স্ট্রিং আপ দখল সবকিছু এটা ব্যবহার করছিলেন stackoverflow.com/a/2477411/1767412 ) এবং আমাকে এক মিনিট নেন উপলব্ধি করা কেন জিনিষ না যাচ্ছিলে পরিকল্পনা
billynoah

1
গ্রহণযোগ্য উত্তর হওয়া উচিত, সম্ভবত সমস্ত বিকল্প থেকে দ্রুত সমাধান।
জন

94

আপনার যদি ডিফেরেন্ট সিস্টেমে নিউলাইনগুলি হ্যান্ডেল করার প্রয়োজন হয় তবে আপনি কেবল পিএইচপি পূর্বনির্ধারিত ধ্রুবক পিএইচপি_ইওল (http://php.net/manual/en/reided.constants.php) ব্যবহার করতে পারেন এবং নিয়মিত এক্সপ্রেশন ইঞ্জিনের ওভারহেড এড়াতে কেবল বিস্ফোরিত ব্যবহার করতে পারেন ।

$lines = explode(PHP_EOL, $subject);

30
সাবধানতা: এটি বিভিন্ন সিস্টেমে কাজ করবে তবে এটি বিভিন্ন সিস্টেমের স্ট্রিংগুলির সাথে ভালভাবে কাজ করবে না । পিএইচপি ম্যানুয়াল বলে যে PHP_EOL (string)হয় চিহ্ন সঠিক 'লাইনের শেষ' এই প্ল্যাটফর্ম।
wadim

@ ওয়াদিম ঠিক বলেছেন! আপনি যদি ইউনিক্স সার্ভারে উইন্ডোজ পাঠ্য ফাইলটি প্রক্রিয়াকরণ করেন তবে এটি ব্যর্থ হবে।
javsmo

1
আপনার লাইনের দৈর্ঘ্যের উপর নির্ভর করে সাবধান থাকুন যে এটি বড় স্ট্রিংগুলির জন্য খুব বড় পরিমাণে মেমরি খেতে পারে।
সিঙ্ক্রো

নোট করুন যে শেষ লাইনে যদি একটি লাইন টার্মিনেটর থাকে তবে এটি এর পরে আর একটি খালি স্ট্রিং ফিরে আসবে।
ডানফোল্ড

20

এটি অত্যধিক জটিল এবং কুরুচিপূর্ণ তবে আমার মতে এটি যাওয়ার উপায়:

$fp = fopen("php://memory", 'r+');
fputs($fp, $data);
rewind($fp);
while($line = fgets($fp)){
  // deal with $line
}
fclose($fp);

1
+1 এবং আপনি php://tempঅস্থায়ী ডিস্ক ফাইলে আরও বড় ডেটা সঞ্চয় করার জন্যও ব্যবহার করতে পারেন ।
কোডএঞ্জ্রি

4
এটি লক্ষ করা উচিত যে এটি আপনাকে স্ট্রোক () সমাধানের বিপরীতে খালি লাইনগুলি সনাক্ত করতে দেয়। ডকুমেন্টেশনটি php.net/manual/en/…
জোসিপ রডিন

7
foreach(preg_split('~[\r\n]+~', $text) as $line){
    if(empty($line) or ctype_space($line)) continue; // skip only spaces
    // if(!strlen($line = trim($line))) continue; // or trim by force and skip empty
    // $line is trimmed and nice here so use it
}

^ এভাবেই আপনি লাইনগুলি সঠিকভাবে ভাঙ্গেন , ক্রস-প্ল্যাটফর্মের সাথে সামঞ্জস্যপূর্ণ Regexp:)


6

এর সাথে সম্ভাব্য মেমরি সমস্যা strtok:

যেহেতু প্রস্তাবিত সমাধানগুলির মধ্যে একটি ব্যবহার করে strtok, দুর্ভাগ্যক্রমে এটি কোনও সম্ভাব্য মেমরি সমস্যা চিহ্নিত করে না (যদিও এটি মেমরি দক্ষ বলে দাবি করে)। ম্যানুয়ালstrtok অনুসারে ব্যবহার করার সময় ,

দ্রষ্টব্য যে কেবল স্ট্রিংকের প্রথম কল স্ট্রিং আর্গুমেন্ট ব্যবহার করে। স্ট্রটকের প্রতিটি পরবর্তী কলকে কেবলমাত্র টোকেন ব্যবহারের প্রয়োজন হয় কারণ এটি বর্তমান স্ট্রিংটিতে কোথায় রয়েছে তা ট্র্যাক করে।

এটি মেমরিতে ফাইল লোড করে এটি করে। আপনি যদি বড় ফাইল ব্যবহার করেন তবে আপনার যদি ফাইলটি লুপিংয়ের কাজ শেষ হয় তবে সেগুলি ফ্লাশ করতে হবে।

<?php
function process($str) {
    $line = strtok($str, PHP_EOL);

    /*do something with the first line here...*/

    while ($line !== FALSE) {
        // get the next line
        $line = strtok(PHP_EOL);

        /*do something with the rest of the lines here...*/

    }
    //the bit that frees up memory
    strtok('', '');
}

যদি আপনি কেবল শারীরিক ফাইলগুলি নিয়ে উদ্বিগ্ন হন (যেমন, ডেটামাইনিং):

ম্যানুয়াল অনুসারে , ফাইল আপলোড অংশের জন্য আপনি fileকমান্ডটি ব্যবহার করতে পারেন :

 //Create the array
 $lines = file( $some_file );

 foreach ( $lines as $line ) {
   //do something here.
 }

4

কিরিলের উত্তরটি সর্বোত্তম বিবেচনা করে আপনাকে বিভিন্ন মেশিনে নিউলাইনগুলি পরিচালনা করতে সক্ষম হওয়া প্রয়োজন।

"আমি বেশিরভাগ দরকারী পিএইচপি ফাংশন খুঁজছি, এটি কীভাবে করা যায় তার জন্য অ্যালগরিদম নয়। কোনও পরামর্শ?"

আমি এগুলি অনেক ব্যবহার করি:

  • বিস্ফোরিত () একটি স্ট্রিমকে একটি অ্যারেতে বিভক্ত করতে ব্যবহার করা যেতে পারে, একটি একক ডেলিফিটর দেওয়া।
  • অ্যারে থেকে স্ট্রিংয়ে ফিরে যাওয়ার জন্য ইমপ্লোড () বিস্ফোরকের পাল্টা।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.