ابحث فقط في العمود الأول من ملف نصي

StackOverflow https://stackoverflow.com/questions/20353653

  •  25-08-2022
  •  | 
  •  

سؤال

لدي ملف نصي مع المحتويات التالية:

---> 12455  ---> 125  ---> KKK
---> 11366  ---> 120  ---> LLL
---> 12477  ---> 120  ---> YYY

أنا أستخدم رمز PHP التالي للبحث في الملف عن "---> 124" وأحصل على النتائج التالية:

---> 12455  ---> 125  ---> KKK
---> 12477  ---> 120  ---> YYY

لكني أريد أن تكون النتائج هكذا:

---> 12455  
---> 12477  

أريده أن يعيد العمود الأول فقط.

<?php
    $file = 'mytext.txt';
    $searchfor = '---> ' . "124";

    // the following line prevents the browser from parsing this as HTML.
    header('Content-Type: text/plain');

    // get the file contents, assuming the file to be readable (and exist)
    $contents = file_get_contents($file);

    // escape special characters in the query
    $pattern = preg_quote($searchfor, '/');

    // finalise the regular expression, matching the whole line
    $pattern = "/^.*$pattern.*\$/m";

    // search, and store all matching occurences in $matches
    if(preg_match_all($pattern, $contents, $matches)) {
        echo implode($matches[0]);
    } else {
        echo "No matches found";
    }
?>
هل كانت مفيدة؟

المحلول

غير نهجك قليلاً. بدلاً من تخزين مصطلح البحث والفاصل في سلسلة واحدة ، استخدم متغيرين.

$sep = '--->';
$searchfor = '124';

$pattern = "/^$sep\s+($searchfor\d+)\s+.*/m";

// search, and store all matching occurences in $matches
if(preg_match_all($pattern, $contents, $matches)){
    echo implode(' ', $matches[1])."\n";
}

المخرجات:

12455 12477

العرض التوضيحي.

نصائح أخرى

بادئ ذي بدء ، انفرف مخاوفك:

  1. اقرأ الملف
  2. تحليل المحتوى
  3. يبحث

باستخدام المتكررين ، يمكنك تحقيق شيء رائع هنا ولكنه سيحتاج إلى فهم أعمق لـ OOP وواجهة Iterator. ما سأوصي به هو نهج أبسط:

<?php
//Read the file line by line
$handle = fopen('file.txt', 'r');
while(!foef($handle)){
    $content = fgets($handle);

    //Parse the line
    $content = explode('---> ', $content);

    //Analyse the line
    if($content[1] == 124){
        echo $content[0]."\n";
    }

}
fclose($handle);

يجب أن يكون ذلك ، فقط قم بتكييفه كما تراه ، لم أختبر الرمز هنا!

يتغيرون "/^.*$pattern.*\$/m" إلى "/$pattern\d*/i"

وثم echo implode($matches[0]); إلى foreach($matches[0] as $item) echo "$item<br />\r\n";

إذا كان الهيكل دائمًا كما أظهرت ، ثم:

  1. قراءة سطر الملف حسب السطر ؛
  2. explode(); كل سطر حسب الفضاء  ;
  3. اقرأ العنصر [1] من النتيجة

يبدو أن هذا أكثر منطقية بالنسبة لي. لا حاجة الى regex هنا ، لأنه سيعمل أبطأ ثم بسيط explode عملية.

هنا مثال:

$handle = fopen( 'file.txt', 'r' );
if ( $handle ) {
    while ( ( $line = fgets( $handle ) ) !== false ) {
        $matches = explode( ' ', $line );
        if ( $matches[4] == '124' )
            echo $matches[1] . '<br/>';
    }
}

جرب هذا:

--->\s\d{5}

Regex مبالغة هنا ، بسيطة explode('--->', $str) واختيار العنصر الأول يكفي

$file = file_get_contents('file.txt');
$lines = explode('---> ', $file);
for($i=1; $i<count($lines); $i=$i+3)
if(strpos($lines[$i], '124')!==false)
    $col[$i/3] = /*'--> ' . */$lines[$i];
print_r($col);

يبدو أن هذا يعمل بشكل جيد. إلغاء التعليق أعلاه إذا كنت تريد -> المدرجة في الإخراج. أيضا ، يتم فهرسة مجموعة $ col الناتجة برقم الصف الذي تم العثور عليه. ما عليك سوى استبدال [$ I/3] بـ [] إذا كنت لا تريد ذلك.

تعزيز هذا:

function SearchFileByColumn($contents, $col_num, $search, $col_count = 3) {
    $segs = explode('---> ', $contents);
    for($i=$col_num; $i<count($segs); $i=$i+$col_count)
        if(strpos($segs[$i], $search) !== false)
            $res[] = $segs[$i];
    return $res;
}

$results = SearchFileByColumn($contents, 1, '124');
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top