اذهب إلى المحتوى

تنسيق النصوص وتحليلها في PHP


سارة محمد2

استيفاء السلسلة النصية

يمكنك استخدام الاستيفاء لتستوفي (تُدرج) متغير في سلسلة نصية (string)، يعمل الاستيفاء مع السلاسل النصية ذات الاقتباس المزدوج وصياغة heredoc فقط.

$name = 'Joel';

// Joel بالاسم $name سيُستبدل المتغير
echo "<p>Hello $name, Nice to see you.</p>";

// "<p>Hello Joel, Nice to see you.</p>"

// كنص خام $name السلاسل النصية ذات الاقتباس المفرد تُظهر المتغير
echo 'Hello $name, Nice to see you.';

// "Hello $name, Nice to see you."

يوفر تنسيق الصياغة المعقدة (صياغة الأقواس المعقوصة) خيارًا آخر يتطلّب أن تغلّف المتغير بأقواس معقوصة {}، يمكن أن يكون هذا مفيدًا عند تضمين المتغيرات في المحتوى النصي للمساعدة في منع الالتباس المحتمل بين المحتوى النصي والمتغيرات.

$name = 'Joel';

// $name مثال باستخدام الأقواس المعقوصة للمتغير
echo "<p>We need more {$name}s to help us!</p>";

// "<p>We need more Joels to help us!</p>"

// غير معرّف `$names` السطر التالي سيرمي خطأً لأنّ
echo "<p>We need more $names to help us!</p>";

// "Notice: Undefined variable: names"

تستوفي صياغة الأقواس المعقوصة {} المتغيرات التي تبدأ بالرمز $ داخل سلسلة نصية، ولا تقيّم تعابير PHP العشوائية.

// PHP مثال يحاول استيفاء تعبير
echo "1 + 2 = {1 + 2}";

// "1 + 2 = {1 + 2}"

// مثال لاستخدام ثابت
define("HELLO_WORLD", "Hello World!!");
echo "My constant is {HELLO_WORLD}";

// "My constant is {HELLO_WORLD}"

// مثال لاستخدام دالة
function say_hello() {
    return "Hello!";
};
echo "I say: {say_hello()}";

// "I say: {say_hello()}"

لكن تقيّم هذه الصياغة الوصول إلى المصفوفة والوصول إلى الخاصيّات واستدعاءات الدالة/التابع على المتغيرات أو عناصر المصفوفة أو الخاصيّات:

// مثال للوصول إلى قيمة من مصفوفة متعددة الأبعاد
$companions = [0 => ['name' => 'Amy Pond'], 1 => ['name' => 'Dave Random']];
echo "The best companion is: {$companions[0]['name']}";

// "The best companion is: Amy Pond"

// مثال لاستدعاء تابع على كائن
class Person {
    function say_hello() {
        return "Hello!";
    }
}

$max = new Person();
echo "Max says: {$max->say_hello()}";

// "Max says: Hello!"

// مثال لاستدعاء دالة مغلِّفة حيث تسمح قائمة المعاملات بتعابير مخصصة
$greet = function($num) {
    return "A $num greetings!";
};
echo "From us all: {$greet(10 ** 3)}";

// "From us all: A 1000 greetings!"

لاحظ أنّ إشارة الدولار $ يمكن أن توجد بعد فتح القوس المعقوص ‎{‎ كما في الأمثلة السابقة، لكن يمكن لها أن توجد قبله كما في سكربت الصدفة (Shell Script) أو لغة Perl:

$name = 'Joel';

// مثال لاستخدام القوس المعقوص مع إشارة الدولار قبل فتح القوس المعقوص
echo "<p>We need more ${name}s to help us!</p>";

// "<p>We need more Joels to help us!</p>"

استخلاص/استبدال أجزاء من السلسلة النصية

يمكن أن تُستخلص المحارف المفردة باستخدام صياغة المصفوفة (الأقواس المعقوفة []) وصياغة الأقواس المعقوصة، تُعيد هاتين الصياغتين محرفًا واحدًا فقط من السلسلة النصية وإذا كنا نريد أكثر من محرف فنحتاج إلى استخدام دالة مثل substr.

تُفهرَس المصفوفات في PHP بدءًا من الصفر.

$foo = 'Hello world';

$foo[6]; // 'w'
$foo{6}; // 'w'

substr($foo, 6, 1); // 'w'
substr($foo, 6, 2); // 'wo'

كما يمكن أن نغيّر محرفًا واحدًا في السلسلة النصية باستخدام صياغتي الأقواس المعقوفة والأقواس المعقوصة أما لتغيير أكثر من محرف نحتاج إلى استخدام دالة مثل substr_replace:

$foo = 'Hello world';

$foo[6] = 'W'; // $foo = 'Hello World'
$foo{6} = 'W'; // $foo = 'Hello World'

substr_replace($foo, 'W', 6, 1); // $foo = 'Hello World'
substr_replace($foo, 'Whi', 6, 2); // 'Hello Whirld'

لاحظ أنّ الجزء السلسلة النصية الجديد ليس بالضرورة أن تكون بنفس طول جزء السلسلة النصيّة المُستبدَل.

تحليل السلسلة النصية

تقسيم سلسلة نصية بفواصل

أسهل التوابع لتقسيم سلسلة نصية هي explode وstrstr.

يمكن تقسيم السلسلة النصية التي تحتوي عدة أجزاء نصيّة يفصل بينها محرف الفاصلة باستخدام الدالة explode.

$fruits = "apple,pear,grapefruit,cherry";
print_r(explode(",",$fruits)); 
// ['apple', 'pear', 'grapefruit', 'cherry']

توفر أيضًا هذه الدالة المعامل limit يمكن استخدامه كالتالي:

$fruits= 'apple,pear,grapefruit,cherry';

إذا كانت قيمة المعامل limit تساوي الصفر فيُتَعَامَل معها على أنها تساوي 1.

print_r(explode(',',$fruits,0)); 
// ['apple,pear,grapefruit,cherry']

أما إذا كانت قيمته موجبةً، فإنّ المصفوفة المُعادة ستحتوي على عناصر بعدد limit، مع احتواء آخر عنصر في المصفوفة على بقية السلسلة النصية:

print_r(explode(',',$fruits,2)); 
// ['apple', 'pear,grapefruit,cherry']

وإذا كانت قيمته سالبةً فستحتوي المصفوفة المعادة على كل محارف السلسلة النصية ما عدا آخر ‎-limit عنصر.

print_r(explode(',',$fruits,-1)); 
// ['apple', 'pear', 'grapefruit']

يمكن أن نجمع بين الدالتين explode وlist لتحويل سلسلة نصية إلى متغيرات في سطرٍ واحد:

$email = "user@example.com";
list($name, $domain) = explode("@", $email);

لكن يجب أن تكون متأكدًا من أنّ نتيجة الدالة explode تحتوي عدد عناصر كافٍ وإلا سينشأ تحذير undefined index.

تزيل الدالة strstr جزء السلسلة النصية الموجود قبل الظهور الأول للمعامل needle المُعطى.

$string = "1:23:456";
echo json_encode(explode(":", $string)); 
// ["1","23","456"]

var_dump(strstr($string, ":")); 
// string(7) ":23:456"

var_dump(strstr($string, ":", true)); 
// string(1) "1"

أجزاء سلسلة نصية

تُعيد الدالة substr جزء السلسلة النصية المحدد بمعاملات موقع البداية وعدد المحارف المطلوبة.

var_dump(substr("Boo", 1)); 
// string(2) "oo"

من الأفضل استخدام mb_substr إذا كان هناك احتمال أن يكون في السلسلة محرفًا متعدد البايتات.

$cake = "cakeæøå";
var_dump(substr($cake, 0, 5)); 
// string(5) "cake�"

var_dump(mb_substr($cake, 0, 5, 'UTF-8')); 
// string(6) "cakeæ"

ولدينا أيضًا الدالة substr_replace تستبدل نصًا ضمن جزء من سلسلة نصية.

var_dump(substr_replace("Boo", "0", 1, 1)); 
// string(3) "B0o"

var_dump(substr_Replace("Boo", "ts", strlen("Boo"))); 
// string(5) "Boots"

بفرض أنّك تريد إيجاد كلمة معينة ضمن سلسلة نصية دون استخدام تعبير نمطي.

$hi = "Hello World!";
$bye = "Goodbye cruel World!";

var_dump(strpos($hi, " ")); 
// int(5)
var_dump(strpos($bye, " ")); 
// int(7)

var_dump(substr($hi, 0, strpos($hi, " "))); 
// string(5) "Hello"
var_dump(substr($bye, -1 * (strlen($bye) - strpos($bye, " ")))); 
// string(13) " cruel World!"

// لموازنة السلاسل النصية strtolower إذا لم تكن حالة الأحرف هامة في النص نستخدم الدالة 
var_dump(substr($hi, 0, strpos($hi, " ")) == 'hello'); 
// bool(false)
var_dump(strtolower(substr($hi, 0, strpos($hi, " "))) == 'hello'); 
// bool(true)

خيار آخر أساسي لتحليل بريد إلكتروني.

$email = "test@example.com";
$wrong = "foobar.co.uk";
$notld = "foo@bar";

$at = strpos($email, "@"); // int(4)
$wat = strpos($wrong, "@"); // bool(false)
$nat = strpos($notld , "@"); // int(3)

$domain = substr($email, $at + 1); // string(11) "example.com"
$womain = substr($wrong, $wat + 1); // string(11) "oobar.co.uk"
$nomain = substr($notld, $nat + 1); // string(3) "bar"

$dot = strpos($domain, "."); // int(7)
$wot = strpos($womain, "."); // int(5)
$not = strpos($nomain, "."); // bool(false)

$tld = substr($domain, $dot + 1); // string(3) "com"
$wld = substr($womain, $wot + 1); // string(5) "co.uk"
$nld = substr($nomain , $not + 1); // string(2) "ar"

// string(25) "test@example.com is valid"
if ($at && $dot) var_dump("$email is valid");
else var_dump("$email is invalid");

// string(21) "foobar.com is invalid"
if ($wat && $wot) var_dump("$wrong is valid");
else var_dump("$wrong is invalid");

// string(18) "foo@bar is invalid"
if ($nat && $not) var_dump("$notld is valid");
else var_dump("$notld is invalid");

// string(27) "foobar.co.uk is an UK email"
if ($tld == "co.uk") var_dump("$email is a UK address");
if ($wld == "co.uk") var_dump("$wrong is a UK address");
if ($nld == "co.uk") var_dump("$notld is a UK address");

أو حتى وضع عبارة "قراءة المزيد" أو "…" في نهاية إعلان ما.

$blurb = "Lorem ipsum dolor sit amet";
$limit = 20;

var_dump(substr($blurb, 0, $limit - 3) . '...'); // string(20) "Lorem ipsum dolor..."

البحث عن جزء من سلسلة نصية باستخدام التابع strpos

يمكن فهم الدالة strpos على أنّها عدد البايتات في المعامل haystack قبل الظهور الأول للمعامل needle.

var_dump(strpos("haystack", "hay")); // int(0)
var_dump(strpos("haystack", "stack")); // int(3)
var_dump(strpos("haystack", "stackoverflow"); // bool(false)

التحقق من وجود جزء من سلسلة نصية

يجب الانتباه عند التحقق للحصول على نتيجة منطقية TRUE أو FALSE، إذ أنّه إذا أرجعت الدالة الفهرس 0 ستُعاملها التعليمة if على أنّها FALSE.

$pos = strpos("abcd", "a"); // $pos = 0;
$pos2 = strpos("abcd", "e"); // $pos2 = FALSE;

// needle مثال خاطئ للتحقق من وجود المعامل
if($pos) { // (1)
    echo "1. I found your string\n";
}
else {
    echo "1. I did not found your string\n";
}

// needle مثال صحيح للتحقق من وجود المعامل
if($pos !== FALSE) {
    echo "2. I found your string\n";
}
else {
    echo "2. I did not found your string\n";
}

// needle التحقق من عدم وجود المعامل
if($pos2 === FALSE) {
    echo "3. I did not found your string\n";
}
else {
    echo "3. I found your string\n";
}

في الموضع (1) لا تتطابق النتيجة 0 مع TRUE.

خرج الشيفرة السابقة:

1. I did not found your string
2. I found your string
3. I did not found your string

البدء بالبحث بعد إزاحة معينة

// يمكننا مع الإزاحة البدء بالبحث متجاهلين كل ما يأتي قبل الإزاحة
$needle = "Hello";
$haystack = "Hello world! Hello World";

$pos = strpos($haystack, $needle, 1); // $pos = 13, not 0

الحصول على كل مرات ظهور جزء من سلسلة نصية

$haystack = "a baby, a cat, a donkey, a fish";
$needle = "a ";
$offsets = [];

// البدء بالبحث من بداية السلسلة النصية
for($offset = 0;$offset < strlen($haystack); ){ // (1)
    $pos = strpos($haystack, $needle, $offset);
    // إذا لم يبقى لدينا أي سلسلة نصية جزئية
    if($pos === false) break;
    $offsets[] = $pos; 
    // (2)
    $offset = $pos + 1;
}
echo json_encode($offsets); // [0,8,15,25]

في الموضع (1) إذا كانت الإزاحة خارج السلسلة النصية فلا تبحث بعد الآن، إذا لم يوضع هذا الشرط سيظهر تحذير إذا انتهى المعامل ‎$haystack بالمعامل ‎$needle وكان طول المعامل ‎$needle بايت واحد.

في الموضع (2) قد ترغب بإضافة strlen($needle)‎ وهذا يعتمد فيما إذا أردت أن تعدّ "aaa" على أنّها سلسلة نصية واحدة أو سلسلتي "aa".

تحليل سلسلة نصية باستخدام التعابير النمطية (regular expressions)

يمكن استخدام الدالة preg_match لتحليل سلسلة نصية باستخدام تعبير نمطي، تُحاط أجزاء التعبير النمطي بأقواس تُدعى أنماطًا فرعية ومعهم يمكنك الحصول على أجزاء فردية من السلسلة النصية.

$str = "<a href=\"http://example.org\">My Link</a>";
$pattern = "/<a href=\"(.*)\">(.*)<\/a>/";
$result = preg_match($pattern, $str, $matches);
if($result === 1) {
    // السلسلة النصية تطابق التعبير النمطي
    print_r($matches);
} else if($result === 0) {
    // لا يوجد تطابق
} else {
    // حدث خطأ
}

الخرج:

Array
(
    [0] => <a href="http://example.org">My Link</a>
    [1] => http://example.org
    [2] => My Link
)

ترجمة -وبتصرف- للفصول [String formatting - String Parsing] من كتاب PHP Notes for Professionals book

اقرأ ايضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...