7. التعبيرات العادية

7.1. نص برمجي [regex-01]
في الدورة التدريبية PHP، استخدمنا الكود التالي لتوضيح التعبيرات العادية في PHP 7:
<?php
// نوع صارم لمعلمات الدوال
declare (strict_types=1);
// التعبيرات العادية في php
// استرداد الحقول المختلفة لسلسلة
// النمط: سلسلة من الأرقام محاطة بأي أحرف
// نريد استرداد سلسلة الأرقام فقط
$modèle = "/(\d+)/";
// مقارنة السلسلة بالنموذج
compareModele2Chaine($modèle, "xyz1234abcd");
compareModele2Chaine($modèle, "12 34");
compareModele2Chaine($modèle, "abcd");
// النموذج: سلسلة من الأرقام محاطة بأي أحرف
// نريد سلسلة الأرقام بالإضافة إلى الحقول التي تليها وتسبقها
$modèle = "/^(.*?)(\d+)(.*?)$/";
// نقوم بمقارنة السلسلة بالنموذج
compareModele2Chaine($modèle, "xyz1234abcd");
compareModele2Chaine($modèle, "12 34");
compareModele2Chaine($modèle, "abcd");
// النموذج - تاريخ بتنسيق يوم/شهر/سنة
$modèle = "/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/";
compareModele2Chaine($modèle, "10/05/97");
compareModele2Chaine($modèle, " 04/04/01 ");
compareModele2Chaine($modèle, "5/1/01");
// القالب - رقم عشري
$modèle = "/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/";
compareModele2Chaine($modèle, "187.8");
compareModele2Chaine($modèle, "-0.6");
compareModele2Chaine($modèle, "4");
compareModele2Chaine($modèle, ".6");
compareModele2Chaine($modèle, "4.");
compareModele2Chaine($modèle, " + 4");
// النهاية
exit;
// --------------------------------------------------------------------------
function compareModele2Chaine(string $modèle, string $chaîne): void {
// مقارنة السلسلة $chaîne بالنموذج $modèle
// مقارنة السلسلة بالنموذج
$champs = [];
$correspond = preg_match($modèle, $chaîne, $champs);
// عرض النتائج
print "\nRésultats($modèle,$chaîne)\n";
if ($correspond) {
for ($i = 0; $i < count($champs); $i++) {
print "champs[$i]=$champs[$i]\n";
}
} else {
print "La chaîne [$chaîne] ne correspond pas au modèle [$modèle]\n";
}
}
نقوم بتحويل هذا الكود إلى جافا سكريبت بالطريقة التالية:
'use strict';
/// التعبيرات العادية في جافا سكريبت
// استرداد الحقول المختلفة لسلسلة
// النمط: سلسلة من الأرقام محاطة بأي أحرف
// نريد استرداد سلسلة الأرقام فقط
let modèle = /(\d+)/;
// مقارنة السلسلة بالنموذج
compareModèleToChaîne(modèle, "xyz1234abcd");
compareModèleToChaîne(modèle, "12 34");
compareModèleToChaîne(modèle, "abcd");
// النمط: سلسلة أرقام محاطة بأحرف عشوائية
// نريد سلسلة الأرقام بالإضافة إلى الحقول التي تليها وتسبقها
modèle = /^(.*?)(\d+)(.*?)$/;
// مقارنة السلسلة بالنموذج
compareModèleToChaîne(modèle, "xyz1234abcd");
compareModèleToChaîne(modèle, "12 34");
compareModèleToChaîne(modèle, "abcd");
// النمط - تاريخ بتنسيق يوم/شهر/سنة
modèle = /^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/;
compareModèleToChaîne(modèle, "10/05/97");
compareModèleToChaîne(modèle, " 04/04/01 ");
compareModèleToChaîne(modèle, "5/1/01");
// القالب - رقم عشري
modèle = /^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$/;
compareModèleToChaîne(modèle, "187.8");
compareModèleToChaîne(modèle, "-0.6");
compareModèleToChaîne(modèle, "4");
compareModèleToChaîne(modèle, ".6");
compareModèleToChaîne(modèle, "4.");
compareModèleToChaîne(modèle, " + 4");
// --------------------------------------------------------------------------
function compareModèleToChaîne(modèle, chaîne) {
// يقارن السلسلة [chaîne] بالنموذج [modèle]
console.log(`----------- chaîne=${chaîne}, modèle=${modèle}`)
// مقارنة السلسلة بالنموذج
const result1 = modèle.exec(chaîne);
console.log(`comparaison avec exec=`, result1);
// طريقة أخرى للقيام بذلك
const result2 = chaîne.match(modèle);
console.log(`comparaison avec match=`, result2);
}
تعليقات
- الرموز PHP و Javascript متقاربة جدًا من بعضها البعض؛
- السطر 7: تجدر الإشارة إلى أن التعبير العادي في جافا سكريبت ليس سلسلة أحرف بل كائن. لا نضع علامات اقتباس أو علامات فاصلة حول التعبير؛
- السطران 41 و44: هناك طريقتان للحصول على نفس النتيجة؛
التنفيذ
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\regexp\regexp-01.js"
type d'une expression régulière : object
----------- chaîne=xyz1234abcd, modèle=/(\d+)/
comparaison avec exec= [ '1234',
'1234',
index: 3,
input: 'xyz1234abcd',
groups: undefined ]
comparaison avec match= [ '1234',
'1234',
index: 3,
input: 'xyz1234abcd',
groups: undefined ]
----------- chaîne=12 34, modèle=/(\d+)/
comparaison avec exec= [ '12', '12', index: 0, input: '12 34', groups: undefined ]
comparaison avec match= [ '12', '12', index: 0, input: '12 34', groups: undefined ]
----------- chaîne=abcd, modèle=/(\d+)/
comparaison avec exec= null
comparaison avec match= null
----------- chaîne=xyz1234abcd, modèle=/^(.*?)(\d+)(.*?)$/
comparaison avec exec= [ 'xyz1234abcd',
'xyz',
'1234',
'abcd',
index: 0,
input: 'xyz1234abcd',
groups: undefined ]
comparaison avec match= [ 'xyz1234abcd',
'xyz',
'1234',
'abcd',
index: 0,
input: 'xyz1234abcd',
groups: undefined ]
----------- chaîne=12 34, modèle=/^(.*?)(\d+)(.*?)$/
comparaison avec exec= [ '12 34',
'',
'12',
' 34',
index: 0,
input: '12 34',
groups: undefined ]
comparaison avec match= [ '12 34',
'',
'12',
' 34',
index: 0,
input: '12 34',
groups: undefined ]
----------- chaîne=abcd, modèle=/^(.*?)(\d+)(.*?)$/
comparaison avec exec= null
comparaison avec match= null
----------- chaîne=10/05/97, modèle=/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/
comparaison avec exec= [ '10/05/97',
'10',
'05',
'97',
index: 0,
input: '10/05/97',
groups: undefined ]
comparaison avec match= [ '10/05/97',
'10',
'05',
'97',
index: 0,
input: '10/05/97',
groups: undefined ]
----------- chaîne= 04/04/01 , modèle=/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/
comparaison avec exec= [ ' 04/04/01 ',
'04',
'04',
'01',
index: 0,
input: ' 04/04/01 ',
groups: undefined ]
comparaison avec match= [ ' 04/04/01 ',
'04',
'04',
'01',
index: 0,
input: ' 04/04/01 ',
groups: undefined ]
----------- chaîne=5/1/01, modèle=/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/
comparaison avec exec= null
comparaison avec match= null
----------- chaîne=187.8, modèle=/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$/
comparaison avec exec= [ '187.8',
'',
'187.8',
index: 0,
input: '187.8',
groups: undefined ]
comparaison avec match= [ '187.8',
'',
'187.8',
index: 0,
input: '187.8',
groups: undefined ]
----------- chaîne=-0.6, modèle=/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$/
comparaison avec exec= [ '-0.6', '-', '0.6', index: 0, input: '-0.6', groups: undefined ]
comparaison avec match= [ '-0.6', '-', '0.6', index: 0, input: '-0.6', groups: undefined ]
----------- chaîne=4, modèle=/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$/
comparaison avec exec= [ '4', '', '4', index: 0, input: '4', groups: undefined ]
comparaison avec match= [ '4', '', '4', index: 0, input: '4', groups: undefined ]
----------- chaîne=.6, modèle=/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$/
comparaison avec exec= [ '.6', '', '.6', index: 0, input: '.6', groups: undefined ]
comparaison avec match= [ '.6', '', '.6', index: 0, input: '.6', groups: undefined ]
----------- chaîne=4., modèle=/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$/
comparaison avec exec= [ '4.', '', '4.', index: 0, input: '4.', groups: undefined ]
comparaison avec match= [ '4.', '', '4.', index: 0, input: '4.', groups: undefined ]
----------- chaîne= + 4, modèle=/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$/
comparaison avec exec= [ ' + 4', '+', '4', index: 0, input: ' + 4', groups: undefined ]
comparaison avec match= [ ' + 4', '+', '4', index: 0, input: ' + 4', groups: undefined ]
تُعطي الطريقتان [regexp.exec] و [string.match] نفس النتائج:
- [null] إذا لم تكن هناك تطابقات بين السلسلة ونموذجها؛
- جدول t، إذا كان هناك تطابق مع:
- t[0]: السلسلة المطابقة للنموذج؛
- t[1]: السلسلة المطابقة للقوس الأول من النموذج؛
- t[2]: السلسلة المطابقة للقوس الثاني من النموذج؛
- …
- t[input]: السلسلة الكاملة التي تم البحث فيها عن النموذج؛
7.2. نص برمجي [regexp-02]
في بعض الأحيان، لا نرغب في استرداد عناصر من السلسلة التي تم اختبارها، بل نرغب فقط في معرفة ما إذا كانت تتطابق مع النموذج:
'use strict';
/// التعبيرات العادية في جافا سكريبت
// استرداد الحقول المختلفة لسلسلة
// النمط: سلسلة من الأرقام محاطة بأي أحرف
// نريد استرداد سلسلة الأرقام فقط
let modèle = /\d+/;
console.log("type d'une expression régulière : ", typeof (modèle));
// مقارنة السلسلة بالنموذج
compareModèleToChaîne(modèle, "xyz1234abcd");
compareModèleToChaîne(modèle, "12 34");
compareModèleToChaîne(modèle, "abcd");
// النموذج: سلسلة من الأرقام محاطة بأحرف عشوائية
// نريد سلسلة الأرقام بالإضافة إلى الحقول التي تليها وتسبقها
modèle = /^.*?\d+.*?$/;
// نقوم بمقارنة السلسلة بالنموذج
compareModèleToChaîne(modèle, "xyz1234abcd");
compareModèleToChaîne(modèle, "12 34");
compareModèleToChaîne(modèle, "abcd");
// القالب - تاريخ بتنسيق يوم/شهر/سنة
modèle = /^\s*\d\d\/\d\d\/\d\d\s*$/;
compareModèleToChaîne(modèle, "10/05/97");
compareModèleToChaîne(modèle, " 04/04/01 ");
compareModèleToChaîne(modèle, "5/1/01");
// القالب - رقم عشري
modèle = /^\s*[+|-]?\s*\d+\.\d*|\.\d+|\d+\s*$/;
compareModèleToChaîne(modèle, "187.8");
compareModèleToChaîne(modèle, "-0.6");
compareModèleToChaîne(modèle, "4");
compareModèleToChaîne(modèle, ".6");
compareModèleToChaîne(modèle, "4.");
compareModèleToChaîne(modèle, " + 4");
// --------------------------------------------------------------------------
function compareModèleToChaîne(modèle, chaîne) {
// اختبار
const correspond = modèle.test(chaîne);
// يقارن السلسلة [chaîne] بالنموذج [modèle]
console.log(`----------- chaîne=${chaîne}, modèle=${modèle}, correspond=${correspond}`);
}
تعليقات
- يستعيد [regexp-02] كود [regexp-01] مع الاختلافات التالية:
- لا نرغب في استرداد عناصر من السلسلة التي يتم اختبارها. لذلك قمنا بإزالة الأقواس في التعبيرات العادية المستخدمة؛
- السطر 40: نستخدم الطريقة [Regexp.test] لمعرفة ما إذا كانت سلسلة الأحرف تتطابق مع تعبير عادي؛
نتائج التنفيذ هي كما يلي:
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\cours\regexp\regexp-02.js"
type d'une expression régulière : object
----------- chaîne=xyz1234abcd, modèle=/\d+/, correspond=true
----------- chaîne=12 34, modèle=/\d+/, correspond=true
----------- chaîne=abcd, modèle=/\d+/, correspond=false
----------- chaîne=xyz1234abcd, modèle=/^.*?\d+.*?$/, correspond=true
----------- chaîne=12 34, modèle=/^.*?\d+.*?$/, correspond=true
----------- chaîne=abcd, modèle=/^.*?\d+.*?$/, correspond=false
----------- chaîne=10/05/97, modèle=/^\s*\d\d\/\d\d\/\d\d\s*$/, correspond=true
----------- chaîne= 04/04/01 , modèle=/^\s*\d\d\/\d\d\/\d\d\s*$/, correspond=true
----------- chaîne=5/1/01, modèle=/^\s*\d\d\/\d\d\/\d\d\s*$/, correspond=false
----------- chaîne=187.8, modèle=/^\s*[+|-]?\s*\d+\.\d*|\.\d+|\d+\s*$/, correspond=true
----------- chaîne=-0.6, modèle=/^\s*[+|-]?\s*\d+\.\d*|\.\d+|\d+\s*$/, correspond=true
----------- chaîne=4, modèle=/^\s*[+|-]?\s*\d+\.\d*|\.\d+|\d+\s*$/, correspond=true
----------- chaîne=.6, modèle=/^\s*[+|-]?\s*\d+\.\d*|\.\d+|\d+\s*$/, correspond=true
----------- chaîne=4., modèle=/^\s*[+|-]?\s*\d+\.\d*|\.\d+|\d+\s*$/, correspond=true
----------- chaîne= + 4, modèle=/^\s*[+|-]?\s*\d+\.\d*|\.\d+|\d+\s*$/, correspond=true
[Done] exited with code=0 in 0.269 seconds