الاثنين، 6 أبريل 2009

Regular Expression في ORACLE 10G

في إصدار أوراكل 10g فإن التوابع (SUBSTR,INSTR,LIKE,REPLACE) قد حسنت لتدعم البحث عن Regular Expression وقد تم إعادة تسمية هذه التوابع في الإصدار الجديد بحيث تم تسميتها REGEXP_SUBSTR,REGEXP_INSTR,REGEXP_LIKE,REGEXP_REPLACE

المستخدمين الذين سبق لهم التعامل مع نظام التشغيل UNIX لن يواجهوا مشكله في فهم هذا الموضوع وخصوصا الذين سبق لهم التعامل مع الاوامر (grep ,sed,awk) فالمفاهيم التي سوف أشرحها هنا متشابهة مع تلك المفاهيم .

ولكن أريد أن أطمئنك عزيزي القارئ بأنك لن تواجه مشكلة في فهم هذا الموضوع إذا لم تكن مستخدما لنظام التشغيل UNIX .

عزيزي القارئ سوف أشرح هذا الموضوع مزودا بالأمثلة فما عليك سوى التطبيق إذا كان إصدار أوراكل لديك 10g.

دعونا نبدأ الموضوع بمثال بفرض أن لديك جدول يحتوي على عمود phone number وله التنسيق التالي :

123-456-7890 فإذا أردت الأرقام الوسطية أي (456) تستطيع أن تختار سلسلة المحارف ضمن عمود رقم الهاتف التي تبدأ وتنتهي بالرمز (-) .

ملاحظة : العمود phone number من نمط varcahr2 لانة يحتوي على الرمز (-).

كيف ستقوم بذلك مع REGEXP_SUBSTR ؟

إذا أنت تريد أن توجد سلسلة المحارف التي تبدأ (-) ومن ثم سلسلة محارف ومن ثم تنتهي بالرمز (-) سوف أضع لك الكود ومن ثم أقوم بشرحه :

Select REGEXP_SUBSTR(‘123-456-7890’, ‘-[^-]+’)

From dual;

Result

-456

ياترى شو اللي صار وشو معنى -[^-]+

اولا الرمز - أنت تخبر أوراكل أن تبحث عن أول محرف يكون (-) وهذا سوف ينتج لنا -456-7890

ثانيا [^-] أما علامة ^ والتي تأتي ضمن الأقواس وتخبر أوراكل أن تقبل جميع المحارف ماعدا المحارف التي تأتي بعد هذا الرمز ^ وهذا يعني لنا أن نحصل على أي محرف ما عدا المحرف (-) مع ملاحظة أن [] تعني محرف واحد ولضمان التكرار وضعنا المحرف + وتعني تكرار أي محرف ما عدا (-) وبهذا نكون قد حصلنا على النتيجة المطلوبة .

لنفرض مثلا أن نريد في المثال السابق أن نحصل على النتيجة التالية (-456-) ياترى كيف سيكون Regular Experssion , سيكون بالشكل التالي ‘-[^-]+-‘ كما تلاحظ عزيزي القاري هذا الأمر يخبر أرواكل أن تبحث هن المحرف - متبوعا بعدد من المحارف (لا ندري عددها) بشرط أن لا يكون أحد هذه المحارف )( وبعد الحصول على هذا التكرار من المحارف يتبع الرمز - (أي تنتهي بالرمز -) بمعنى آخر أوراكل سوف تبحث عن السلسلة التي تبدأ (-) وتنتهي ب (-) وبينهما سلسلة من المحارف شرط ان لايكون أحد المحارف (-) إليك الكود

Select REGEXP_SUBSTR(‘123-456-7890’, ‘-[^-]+-’)

From dual;

Result

-456-

عزيزي القارئ لقد سهل هذا التابع العمل فلو أردت الحصول على النتيجة السابقة (-456) بدون استخدام REGEXP_SUBSTR سيكون لديك الكثير من الوقت والتفكير لتحل هذه المعضلة , لاحظ الكود التالي :

select substr('123-456-7890',instr('123-456-7890','-',1,1),

instr('123-456-7890','-',1,2)-

instr('123-456-7890','-',1,1)) from dual;


حيث أن : instr('123-456-7890','-',1,1) سوف تعطيك أول تكرار لعلامة (-) والنتيجة هي : 4 .

instr('123-456-7890','-',1,2) : سوف تعطيك ثاني تكرار لعلامة (-) والنتيجة هي 8 .

وبالتالي سوف تحصل على substr('123-456-7890',4,4) وهي التي تعيد لك النتيجة , ولو حاولت كتابة هذه التابع كما هو أي substr('123-456-7890',4,4) في عبارة الاستعلام فلن تضمن الحصول على النتيجة فقد يكون رقم الهاتف بالشكل التالي 1234-4567-7890 عندها لن تحصل على النتيجة المطلوبة .

أعتقد أنك وصلت لقرار أن REGEXP_SUBSTR أكثر إختصارا , دعني أعطيك مثال آخر إذا أردت الحصول على الرمز (:) ضمن سلسة نصية فكيف ستقوم بذلك

Select REGEXP_SUBSTR(‘MY LEDGER: Debits, Credits, and Invoices 1940’,’[:punct:]’ ) from dual;

ستسال نفسك من أين يأتي بهذه الرموز إليك الرابط التالي :

إليك مزيد من الأمثلة :

Select REGEXP_SUBSTR(‘MY LEDGER: Debits, Credits, and Invoices 1940’,’[:punct:][^,]+,’ ) from dual;

Result ( : Debits,)

Select REGEXP_SUBSTR(‘MY LEDGER: Debits, Credits, and Invoices 1940’,’[[:digit:]]+’ ) from dual;

Result (1940)


ستجد في هذا الرابط جميع عمليات Regular Expression مع الوصف لك عملية :

http://www.sc.ehu.es/siwebso/KZCC/Or...5/adfns_re.htm

REGEXP_SUBSTR

يعيد هذا التابع سلسلة محارف من نمط Varchar2 أو من نمط معطيات CLOB

ولها الـ syntax التالي :

REGEXP_SUBSRT(source_string,pattern

[,postion

[,occurrence

[,match_parameter]

]

]

)

source_string : وهذا البارامتر عبارة عن سلسلة المحارف أو اسم العمود من جدول والمراد تطبيق التابع علية .

pattern : كما لاحظتم سابقا مجموعة الرموز التي استخدمناها في المثال الأول تمثل هذا البارامتر وهي عبارة عن regular expression ويمكن أن يصل طول هذا البارامتر 512 bytes

Position : هذا البارامتر يحدد القيمة (Integer) من أين سيبدأ التابع بالبحث ضمن source_string القيمة الافتراضية له (1) وهذا يعني أن البحث سيبدأ من المحرف الأول في السلسلة .

Occurrence : هذا البارامتر (Integer) وتحدد رقم التكرار للسلسلة المحددة في ال pattern والتي سيتم البحث عنها ضمن source_string والقيمة الافتراضية (1) وتعني الحصول على التكرار الأول .

ملاحظة : المتحولان الأخيرين غير موجودين في الإصدار السابق SUBSTR , وهذين المتحولان إذا فكرت قليلا يدمجان إمكانيات التابع Substr مع التابع INSTR كما لاحظتم في المثال السابق .

والأجمل والأروع من ذلك كله هذا المتحول match_parameter وهو متحول محرفي وله عدة قيم :

1- ‘i’ : عدم الحساسية لحالة الأحرف

2- ‘c’ : التحسس لحالة الأحرف .

وهناك غيرها من القيم بإمكانك الإطلاع عليها في Oracle Documentation .

الآن سوف نستعرض الأمثلة التي توضح الفكرة بالأعلى :

Select REGEXP_SUBSTR(‘MY LEDGER: Debits, Credits, and Invoices 1940’,’my’,1,1,’i’ ) from dual;

Result ( MY )

في هذا المثال كما تلاحظون أن نريد الحصول التكرار الأول للـ my وأن يبدأ البحث في السلسلة ابتدءا من المحرف الأول مع عدم التحسس لحالة الأحرف .

في المثال السابق لو استبدلنا ‘i’ ب ‘c’ فأن النتيجة ستكون NULL .

مثال آخر :

Select REGEXP_SUBSTR(‘MY LEDGER: Debits, Credits, and Invoices 1940’,’[[:digit:]]’,1,2 ) from dual;

Result (9)

في هذا المثال فأن نريد البحث عن رقم كما تلاحظ ال Pattern ([[:digit:]]) وتعني الحصول على رقم وتعني رقم واحد فقط بحيث يبدأ البحث من المحرف الأول من سلسلة البحث ولا بد أن نحصل على التكرار الثاني وكما تلاحظون النتيجة .

حاول كتابة هذا الاستعلام باستخدام Substr و instr ؟ أتستطيع فعل هذا ؟

أخواني ألتمس منكم العذر لعدم إكمال شرح بقية التوابع لأنها تشبه تماما هذا التابع ولفهمك لهذا التابع لن تجد أي صعوبة في فهم بقية التوابع (REGEXP_INSTR,REGEXP_LIKE,REGEXP_REPLACE) ما عليك سوف البحث عن هذه التوابع على الانترنت أو من Oracle Documentation .

ليست هناك تعليقات:

إرسال تعليق

Powered By Blogger