الفرق بين المراجعتين ل"Ruby/Regexp"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
سطر 1: سطر 1:
<noinclude>{{DISPLAYTITLE: صفحة الصنف <code>Regexp</code> في روبي}}</noinclude>
 
[[تصنيف: Ruby]]
 
[[تصنيف: Ruby Regexp]]
 
 
كائنات الصنف <code>Regexp</code> التعابير النمطية، والتي تُستخدم لمطابقة نمط (pattern) معيّن في سلسلة نصية. يتم إنشاء التعابير النمطية باستخدام الصياغتين <code>/.../</code> و ‎<code>%r{...}‎</code>، أو بالمنشئ <code>[[Ruby/Regexp/new|new]]</code>.
 
كائنات الصنف <code>Regexp</code> التعابير النمطية، والتي تُستخدم لمطابقة نمط (pattern) معيّن في سلسلة نصية. يتم إنشاء التعابير النمطية باستخدام الصياغتين <code>/.../</code> و ‎<code>%r{...}‎</code>، أو بالمنشئ <code>[[Ruby/Regexp/new|new]]</code>.
  
سطر 13: سطر 10:
 
‎</syntaxhighlight>أماا في هذا المثال، فالسلسلة النصية <code>'haystack'</code> تحتوي على النمط <code>'hay'</code>، لذلك فهي تتطابق:<syntaxhighlight lang="ruby">/hay/.match('haystack')    #=> #<MatchData "hay">
 
‎</syntaxhighlight>أماا في هذا المثال، فالسلسلة النصية <code>'haystack'</code> تحتوي على النمط <code>'hay'</code>، لذلك فهي تتطابق:<syntaxhighlight lang="ruby">/hay/.match('haystack')    #=> #<MatchData "hay">
 
‎</syntaxhighlight>بشكل أكثر تحديدًا، يتطلب التعبير النمطي <code>/st/</code> أن تحتوي السلسلة النصية على الحرف <code>s</code> متبوعاً بالحرف <code>t</code> ، لذلك فهي تتطابق مع <code>"haystack"</code> أيضًا.
 
‎</syntaxhighlight>بشكل أكثر تحديدًا، يتطلب التعبير النمطي <code>/st/</code> أن تحتوي السلسلة النصية على الحرف <code>s</code> متبوعاً بالحرف <code>t</code> ، لذلك فهي تتطابق مع <code>"haystack"</code> أيضًا.
 
+
==المعامل ‎<code>[[Ruby/Regexp/3D~|=~]]</code> ‎و التابع <code>[[Ruby/Regexp/match|match]]</code>==
== المعامل ‎<code>[[Ruby/Regexp/3D~|=~]]</code> ‎و التابع <code>[[Ruby/Regexp/match|match]]</code> ==
 
 
يمكن التحقق من مطابقة النمط باستخدام المعامل ‎<code>[[Ruby/Regexp/3D~|=~‎]]</code> أو التابع <code>[[Ruby/Regexp/match|match]]</code>.
 
يمكن التحقق من مطابقة النمط باستخدام المعامل ‎<code>[[Ruby/Regexp/3D~|=~‎]]</code> أو التابع <code>[[Ruby/Regexp/match|match]]</code>.
 
+
===المعامل ‎<code>[[Ruby/Regexp/3D~|=~‎]]</code>===
=== المعامل ‎<code>[[Ruby/Regexp/3D~|=~‎]]</code> ===
 
 
‎<code>[[Ruby/Regexp/3D~|=~‎]]</code> هو معامل المُطابقة الأساسي في روبي.  عندما يكون أحد معامليه عبارة عن تعبير نمطي، والآخر عبارة عن سلسلة نصية، فسيُستخدم التعبير النمطي حينها كنمط لمطابقة السلسلة النصية.  (تعريف هذا المعامل في الصنفين <code>Regexp</code> و <code>[[Ruby/String|String]]</code> متماثل، لذا لا يهم ترتيب السلسلة النصية أو التعبيرالنمطي لا يهم. قد يكون للأصناف الأخرى تقديمات (implementations) مختلفة للمعامل ‎<code>[[Ruby/Regexp/3D~|=~‎]]</code>.)  في حالة العثور على تطابق، فسيعيد المعامل فهرس المطابقة الأولى في السلسلة النصية، وإلا فسيعيد <code>nil</code>.<syntaxhighlight lang="ruby">/hay/ =~ 'haystack'  #=> 0
 
‎<code>[[Ruby/Regexp/3D~|=~‎]]</code> هو معامل المُطابقة الأساسي في روبي.  عندما يكون أحد معامليه عبارة عن تعبير نمطي، والآخر عبارة عن سلسلة نصية، فسيُستخدم التعبير النمطي حينها كنمط لمطابقة السلسلة النصية.  (تعريف هذا المعامل في الصنفين <code>Regexp</code> و <code>[[Ruby/String|String]]</code> متماثل، لذا لا يهم ترتيب السلسلة النصية أو التعبيرالنمطي لا يهم. قد يكون للأصناف الأخرى تقديمات (implementations) مختلفة للمعامل ‎<code>[[Ruby/Regexp/3D~|=~‎]]</code>.)  في حالة العثور على تطابق، فسيعيد المعامل فهرس المطابقة الأولى في السلسلة النصية، وإلا فسيعيد <code>nil</code>.<syntaxhighlight lang="ruby">/hay/ =~ 'haystack'  #=> 0
 
'haystack' =~ /hay/  #=> 0
 
'haystack' =~ /hay/  #=> 0
سطر 24: سطر 19:
  
 
التابع<code>[[Ruby/Regexp/last match|last_match]]</code> مكافئ للمتغير ‎<code>$~‎</code>.
 
التابع<code>[[Ruby/Regexp/last match|last_match]]</code> مكافئ للمتغير ‎<code>$~‎</code>.
 
+
===التابع <code>[[Ruby/Regexp/match|match]]</code>===
=== التابع <code>[[Ruby/Regexp/match|match]]</code> ===
 
 
يعيد التابع <code>[[Ruby/Regexp/match|match]]</code> كائنًا من النوع <code>[[Ruby/MatchData|MatchData]]</code>:<syntaxhighlight lang="ruby">/st/.match('haystack')  #=> #<MatchData "st"></syntaxhighlight>
 
يعيد التابع <code>[[Ruby/Regexp/match|match]]</code> كائنًا من النوع <code>[[Ruby/MatchData|MatchData]]</code>:<syntaxhighlight lang="ruby">/st/.match('haystack')  #=> #<MatchData "st"></syntaxhighlight>
 
+
===الحروف الخاصة (Metacharacters) وحروف التخليص (Escapes)===
=== الحروف الخاصة (Metacharacters) وحروف التخليص (Escapes) ===
 
 
الحروف التالية هي حروف خاصة (''metacharacters''):
 
الحروف التالية هي حروف خاصة (''metacharacters''):
  
سطر 39: سطر 32:
 
     #=> #<MatchData "東京都">
 
     #=> #<MatchData "東京都">
 
‎</syntaxhighlight>
 
‎</syntaxhighlight>
 
+
==مجموعات الحروف (Character Classes)==
== مجموعات الحروف (Character Classes) ==
 
 
يتم تحديد مجموعات الحروف (''character class'') بواسطة الأقواس المربعة (<code>[</code> ، <code>]</code>) وتوضع بينها الأحرف التي قد تظهر عند هذه النقطة في المطابقة. التعبير النمطي <code>/[ab]/</code> يعني إما <code>a</code> أو <code>b</code>، على خلاف <code>/ab/</code> الذي يعني الحرف <code>a</code> متبوعاً بالحرف <code>b</code>.<syntaxhighlight lang="ruby">/W[aeiou]rd/.match("Word") #=> #<MatchData "Word"></syntaxhighlight>ضمن مجموعات الحروف، تمثل الشرطة (<code>-</code>) حرفًا خاصا يشير إلى مجال شامل (inclusive) مكون من أحرف. التعبير النمطي <code>[abcd]</code> يكافئ <code>[a-d]</code>. يمكن أن يُتبع المجال بمجال آخر، لذلك فالتعبير النمطي <code>[abcdwxyz]</code> يكافئ <code>[a-dw-z]</code>. ولا يهم الترتيب الذي تظهر به المجالات أو الأحرف الفردية داخل مجموعة الحروف.<syntaxhighlight lang="ruby">/[0-9a-f]/.match('9f') #=> #<MatchData "9">
 
يتم تحديد مجموعات الحروف (''character class'') بواسطة الأقواس المربعة (<code>[</code> ، <code>]</code>) وتوضع بينها الأحرف التي قد تظهر عند هذه النقطة في المطابقة. التعبير النمطي <code>/[ab]/</code> يعني إما <code>a</code> أو <code>b</code>، على خلاف <code>/ab/</code> الذي يعني الحرف <code>a</code> متبوعاً بالحرف <code>b</code>.<syntaxhighlight lang="ruby">/W[aeiou]rd/.match("Word") #=> #<MatchData "Word"></syntaxhighlight>ضمن مجموعات الحروف، تمثل الشرطة (<code>-</code>) حرفًا خاصا يشير إلى مجال شامل (inclusive) مكون من أحرف. التعبير النمطي <code>[abcd]</code> يكافئ <code>[a-d]</code>. يمكن أن يُتبع المجال بمجال آخر، لذلك فالتعبير النمطي <code>[abcdwxyz]</code> يكافئ <code>[a-dw-z]</code>. ولا يهم الترتيب الذي تظهر به المجالات أو الأحرف الفردية داخل مجموعة الحروف.<syntaxhighlight lang="ruby">/[0-9a-f]/.match('9f') #=> #<MatchData "9">
 
/[9f]/.match('9f')    #=> #<MatchData "9"></syntaxhighlight>إذا كان أول حرف من حروف المجموعة هو العلامة (<code>^</code>)، فستُعكس المجموعة: أي أنها ستطابق أي حرف باستثناء تلك المحددة في المجموعة.<syntaxhighlight lang="ruby">/[^a-eg-z]/.match('f') #=> #<MatchData "f"></syntaxhighlight>يمكن أن تحتوي مجموعة حروف على مجموعة حروف أخرى. الشكل ‎<code>[a-z[0-9]]‎</code> يصف نفس المجموعة <code>[a-z0-9]</code>. كما أنّ مجموعات الحروف تدعم المعامل <code>&&</code> الذي يجري عملية التقاطع على وسائطه. ويمكن دمج الاثنين كما يلي:<syntaxhighlight lang="ruby">/[a-w&&[^c-g]z]/ # ([a-w] AND ([^c-g] OR z))</syntaxhighlight>هذا يُكافئ:<syntaxhighlight lang="ruby">/[abh-w]/</syntaxhighlight>تتصرف الحروف الخاصة (metacharacters) التالية مثل مجموعات الحروف:
 
/[9f]/.match('9f')    #=> #<MatchData "9"></syntaxhighlight>إذا كان أول حرف من حروف المجموعة هو العلامة (<code>^</code>)، فستُعكس المجموعة: أي أنها ستطابق أي حرف باستثناء تلك المحددة في المجموعة.<syntaxhighlight lang="ruby">/[^a-eg-z]/.match('f') #=> #<MatchData "f"></syntaxhighlight>يمكن أن تحتوي مجموعة حروف على مجموعة حروف أخرى. الشكل ‎<code>[a-z[0-9]]‎</code> يصف نفس المجموعة <code>[a-z0-9]</code>. كما أنّ مجموعات الحروف تدعم المعامل <code>&&</code> الذي يجري عملية التقاطع على وسائطه. ويمكن دمج الاثنين كما يلي:<syntaxhighlight lang="ruby">/[a-w&&[^c-g]z]/ # ([a-w] AND ([^c-g] OR z))</syntaxhighlight>هذا يُكافئ:<syntaxhighlight lang="ruby">/[abh-w]/</syntaxhighlight>تتصرف الحروف الخاصة (metacharacters) التالية مثل مجموعات الحروف:
* <code>/./</code> - أي حرف باستثناء محرف السطر الجديد.
+
*<code>/./</code> - أي حرف باستثناء محرف السطر الجديد.
* ‎<code>/./m</code> - أي حرف (المُعدِّل <code>m</code> يتيح الوضع متعدد الأسطر)
+
*‎<code>/./m</code> - أي حرف (المُعدِّل <code>m</code> يتيح الوضع متعدد الأسطر)
* ‎<code>/\w/‎</code> - حرف كلمة (<code>[a-zA-Z0-9_‎]</code>)
+
*‎<code>/\w/‎</code> - حرف كلمة (<code>[a-zA-Z0-9_‎]</code>)
* ‎‎‎‎‎<code>/\W/‎</code> - ُحرف يخالف حروف الكلمة (<code>[‎^a-zA-Z0-9_‎‎]</code>). يرجى إلقاء نظرة على صفحة الخطأ <code>[https://bugs.ruby-lang.org/issues/4044 Bug#4044]</code> في حالة استخدام <code>‎‎‎‎‎/\W/‎</code>  مع المُعدِّل ‎<code>/i‎</code>.
+
*‎‎‎‎‎<code>/\W/‎</code> - ُحرف يخالف حروف الكلمة (<code>[‎^a-zA-Z0-9_‎‎]</code>). يرجى إلقاء نظرة على صفحة الخطأ <code>[https://bugs.ruby-lang.org/issues/4044 Bug#4044]</code> في حالة استخدام <code>‎‎‎‎‎/\W/‎</code>  مع المُعدِّل ‎<code>/i‎</code>.
  
* ‎<code>/\d/‎</code> - حرف رقمي (<code>[‎0-9]</code>)  
+
*‎<code>/\d/‎</code> - حرف رقمي (<code>[‎0-9]</code>)
* ‎<code>/\D/‎</code> - حرف غير رقمي (<code>[‎^0-9]</code>)  
+
*‎<code>/\D/‎</code> - حرف غير رقمي (<code>[‎^0-9]</code>)
* ‎<code>/\h/</code> ‎- حرف ستة عشري (<code>[‎0-9a-fA-F]</code>)
+
*‎<code>/\h/</code> ‎- حرف ستة عشري (<code>[‎0-9a-fA-F]</code>)
* ‎<code>/\H/‎</code> - حرف غير ستة عشري (<code>[‎^0-9a-fA-F]</code>)  
+
*‎<code>/\H/‎</code> - حرف غير ستة عشري (<code>[‎^0-9a-fA-F]</code>)
* ‎<code>/\s/‎</code> - حرف من حروف المسافات البيضاء: <code>/[‎ \t\r\n\f\v]/</code>
+
*‎<code>/\s/‎</code> - حرف من حروف المسافات البيضاء: <code>/[‎ \t\r\n\f\v]/</code>
* ‎<code>/\S/‎</code> - حرف يخالف حروف المسافة البيضاء: <code>/[‎^‎ \t\r\n\f\v]/</code>  
+
*‎<code>/\S/‎</code> - حرف يخالف حروف المسافة البيضاء: <code>/[‎^‎ \t\r\n\f\v]/</code>
تعبيرات أقواس POSIX ‏(POSIX ''bracket expressions'') مشابهة لمجموعات الحروف. إذ توفر بديلاً محمولًا (portable) لما سبق، مع ميزة إضافية تتمثل في أنها يمكن أن تحتوي على أحرف من خارج الترميز ASCII. على سبيل المثال، لا يطابق التعبير ‏‏‎<code>/\d/‎‏</code> إلا الأرقام العشرية للترميز ASCII ‏(0-9)؛ بينما يطابق التعبير<code> /<nowiki>[[:digit:]]</nowiki>/</code> أي حرف من مجموعة الحروف العددية Nd  في اليونيكود (Unicode Nd).  
+
تعبيرات أقواس POSIX ‏(POSIX ''bracket expressions'') مشابهة لمجموعات الحروف. إذ توفر بديلاً محمولًا (portable) لما سبق، مع ميزة إضافية تتمثل في أنها يمكن أن تحتوي على أحرف من خارج الترميز ASCII. على سبيل المثال، لا يطابق التعبير ‏‏‎<code>/\d/‎‏</code> إلا الأرقام العشرية للترميز ASCII ‏(0-9)؛ بينما يطابق التعبير<code> /<nowiki>[[:digit:]]</nowiki>/</code> أي حرف من مجموعة الحروف العددية Nd  في اليونيكود (Unicode Nd).
* <code>/<nowiki>[[:alnum:]]</nowiki>/</code>- حرف أبجدي أو رقم  
+
*<code>/<nowiki>[[:alnum:]]</nowiki>/</code>- حرف أبجدي أو رقم
* <code>/<nowiki>[[:alpha:]]</nowiki>/</code> - حرف أبجدي  
+
*<code>/<nowiki>[[:alpha:]]</nowiki>/</code> - حرف أبجدي
* <code>/<nowiki>[[:blank:]]</nowiki>/</code> - فراغ أو  علامة تبويب (tab)
+
*<code>/<nowiki>[[:blank:]]</nowiki>/</code> - فراغ أو  علامة تبويب (tab)
* <code>/<nowiki>[[:cntrl:]]</nowiki>/</code> - حرف تحكم (Control character)
+
*<code>/<nowiki>[[:cntrl:]]</nowiki>/</code> - حرف تحكم (Control character)
  
* <code>/<nowiki>[[:digit:]]</nowiki>/</code> - رقم  
+
*<code>/<nowiki>[[:digit:]]</nowiki>/</code> - رقم
* <code>/<nowiki>[[:graph:]]</nowiki>/</code> - حرف غير فارغ (يستثني المسافات وأحرف التحكم وما شابه)  
+
*<code>/<nowiki>[[:graph:]]</nowiki>/</code> - حرف غير فارغ (يستثني المسافات وأحرف التحكم وما شابه)
* <code>/<nowiki>[[:lower:]]</nowiki>/</code> - الأحرف الأبجدية الصغيرة  
+
*<code>/<nowiki>[[:lower:]]</nowiki>/</code> - الأحرف الأبجدية الصغيرة
* <code>/<nowiki>[[:print:]]</nowiki>/</code> - مثل <code>[:graph:]</code>، ولكنها تتضمن حرف المسافة  
+
*<code>/<nowiki>[[:print:]]</nowiki>/</code> - مثل <code>[:graph:]</code>، ولكنها تتضمن حرف المسافة
* <code>/<nowiki>[[:punct:]]</nowiki>/</code> - علامة ترقيم (Punctuation character)
+
*<code>/<nowiki>[[:punct:]]</nowiki>/</code> - علامة ترقيم (Punctuation character)
* <code>/<nowiki>[[:space:]]</nowiki>/</code> - محرف مسافة بيضاء (<code>[:blank:]</code> أو سطر جديد أو حرف الرجوع [carriage return]، وما إلى ذلك)
+
*<code>/<nowiki>[[:space:]]</nowiki>/</code> - محرف مسافة بيضاء (<code>[:blank:]</code> أو سطر جديد أو حرف الرجوع [carriage return]، وما إلى ذلك)
* <code>/<nowiki>[[:upper:]]</nowiki>/</code> - حرف أبجدي كبير  
+
*<code>/<nowiki>[[:upper:]]</nowiki>/</code> - حرف أبجدي كبير
* <code>/<nowiki>[[:xdigit:]]</nowiki>/</code> - رقم من الأرقام المسموح بها في الأعداد السداسي عشرية (أي الحروف ‎<code>0-9a-fA-F</code>)  
+
*<code>/<nowiki>[[:xdigit:]]</nowiki>/</code> - رقم من الأرقام المسموح بها في الأعداد السداسي عشرية (أي الحروف ‎<code>0-9a-fA-F</code>)
 
تدعم روبي أيضًا مجموعات الحروف التالية بجانب مجموعات POSIX:
 
تدعم روبي أيضًا مجموعات الحروف التالية بجانب مجموعات POSIX:
* <code>/<nowiki>[[:word:]]</nowiki>/</code> - حرف من إحدى مجموعات حروف اليونيكود العامة التالية <code>Letter</code> و <code>Mark</code> و <code>Number</code> و <code>Connector_Punctuation</code>.  
+
*<code>/<nowiki>[[:word:]]</nowiki>/</code> - حرف من إحدى مجموعات حروف اليونيكود العامة التالية <code>Letter</code> و <code>Mark</code> و <code>Number</code> و <code>Connector_Punctuation</code>.
* <code>/<nowiki>[[:ascii:]]</nowiki>/</code> - حرف من مجموعة حروف ASCII.
+
*<code>/<nowiki>[[:ascii:]]</nowiki>/</code> - حرف من مجموعة حروف ASCII.
 
<syntaxhighlight lang="ruby"># U+06F2 is "EXTENDED ARABIC-INDIC DIGIT TWO"
 
<syntaxhighlight lang="ruby"># U+06F2 is "EXTENDED ARABIC-INDIC DIGIT TWO"
 
/[[:digit:]]/.match("\u06F2")    #=> #<MatchData "\u{06F2}">
 
/[[:digit:]]/.match("\u06F2")    #=> #<MatchData "\u{06F2}">
 
/[[:upper:]][[:lower:]]/.match("Hello") #=> #<MatchData "He">
 
/[[:upper:]][[:lower:]]/.match("Hello") #=> #<MatchData "He">
 
/[[:xdigit:]][[:xdigit:]]/.match("A6")  #=> #<MatchData "A6"></syntaxhighlight>
 
/[[:xdigit:]][[:xdigit:]]/.match("A6")  #=> #<MatchData "A6"></syntaxhighlight>
 
+
==التكرار==
== التكرار ==
 
 
تتطابق التركيبات الموصوفة حتى الآن مع حرف واحد، لكن ماذا لو أردنا مطابقة أكثر من حرف دفعة واحدة. يمكننا ذلك باستخدام حروف خاصة تُسمى المُكممات (quantifiers). والتي توضع بعد الحرف الذي نريد أن يتكرر  لتحديد عدد مرات ظهوره، هذه المكممات هي:
 
تتطابق التركيبات الموصوفة حتى الآن مع حرف واحد، لكن ماذا لو أردنا مطابقة أكثر من حرف دفعة واحدة. يمكننا ذلك باستخدام حروف خاصة تُسمى المُكممات (quantifiers). والتي توضع بعد الحرف الذي نريد أن يتكرر  لتحديد عدد مرات ظهوره، هذه المكممات هي:
* <code>*</code> - صفر مرّة أو أكثر.  
+
*<code>*</code> - صفر مرّة أو أكثر.
* <code>+</code>  - مرة واحدة أو أكثر  
+
*<code>+</code>  - مرة واحدة أو أكثر
* <code>?</code>  - صفر مرة أو مرة واحدة (اختياري)
+
*<code>?</code>  - صفر مرة أو مرة واحدة (اختياري)
* <code>{</code>n<code>}</code> - بالضبط n مرة  
+
*<code>{</code>n<code>}</code> - بالضبط n مرة
* <code>{</code>n<code>,}</code> - على الأقل أكثر n مرة  
+
*<code>{</code>n<code>,}</code> - على الأقل أكثر n مرة
* <code>{,</code>m<code>}</code> - على الأكثر m مرة  
+
*<code>{,</code>m<code>}</code> - على الأكثر m مرة
* <code>{</code>n<code>,</code>m<code>}</code> - بين n و m مرة  
+
*<code>{</code>n<code>,</code>m<code>}</code> - بين n و m مرة
 
'مثال': على الأقل حرف كبير واحد ('<code>H</code>')، ثم حرف واحد صغير على الأقل ('<code>e</code>')، ثم حرفين <code>'l</code>'، ثم حرف '<code>o</code>':<syntaxhighlight lang="ruby">"Hello".match(/[[:upper:]]+[[:lower:]]+l{2}o/) #=> #<MatchData "Hello"></syntaxhighlight>أنماط التكرار طمّاعة (greedy) افتراضيًا: أي أنها تبحث عن مطابقة أكبر جزء ممكن يحقق المطابقة من السلسلة النصية. على خلاف ذلك، فإن المطابقة القانعة (lazy matching) تكتفي بالحد الأدنى من السلسلة النصية الذي يحقق المطابقة بشكل عام.
 
'مثال': على الأقل حرف كبير واحد ('<code>H</code>')، ثم حرف واحد صغير على الأقل ('<code>e</code>')، ثم حرفين <code>'l</code>'، ثم حرف '<code>o</code>':<syntaxhighlight lang="ruby">"Hello".match(/[[:upper:]]+[[:lower:]]+l{2}o/) #=> #<MatchData "Hello"></syntaxhighlight>أنماط التكرار طمّاعة (greedy) افتراضيًا: أي أنها تبحث عن مطابقة أكبر جزء ممكن يحقق المطابقة من السلسلة النصية. على خلاف ذلك، فإن المطابقة القانعة (lazy matching) تكتفي بالحد الأدنى من السلسلة النصية الذي يحقق المطابقة بشكل عام.
  
سطر 91: سطر 82:
 
كلا النمطين أدناه يتطابقان مع السلسلة النصية. يستخدم الأول مُكمما طماعًا، بحيث يطابق "<code>‎.+‎</code>" السلسة النصية "<a> " ؛ أما الثاني فيستخدم مكمما قانعا،بحيث يطابق '‎<code>.+?‎</code>'السلسلة النصية '<a>':<syntaxhighlight lang="ruby">/<.+>/.match("<a><b>")  #=> #<MatchData "<a><b>">
 
كلا النمطين أدناه يتطابقان مع السلسلة النصية. يستخدم الأول مُكمما طماعًا، بحيث يطابق "<code>‎.+‎</code>" السلسة النصية "<a> " ؛ أما الثاني فيستخدم مكمما قانعا،بحيث يطابق '‎<code>.+?‎</code>'السلسلة النصية '<a>':<syntaxhighlight lang="ruby">/<.+>/.match("<a><b>")  #=> #<MatchData "<a><b>">
 
/<.+?>/.match("<a><b>") #=> #<MatchData "<a>"></syntaxhighlight>المكممات المتبوعة بالعلامة <code>+</code> تُطابق  تملكيًا (possessively): فبمجرد أن تُطابق نمطًا فلن تتراجع. فهي تتصرف مثل المكممات الطماعة، ولكنها ترفض "التخلي" عن الأجزاء التي طابقتها حتى لو كان ذلك سيُفشل كامل المطابقة.
 
/<.+?>/.match("<a><b>") #=> #<MatchData "<a>"></syntaxhighlight>المكممات المتبوعة بالعلامة <code>+</code> تُطابق  تملكيًا (possessively): فبمجرد أن تُطابق نمطًا فلن تتراجع. فهي تتصرف مثل المكممات الطماعة، ولكنها ترفض "التخلي" عن الأجزاء التي طابقتها حتى لو كان ذلك سيُفشل كامل المطابقة.
 
+
==الالتقاط (Capturing)==
== الالتقاط (Capturing) ==
 
 
 
 
يمكن استخدام الأقواس لأجل الالتقاط (capturing). ويمكن لاحقًا التأشير إلى النص المتضمن في مجموعة الأقواس رقم <code>n</code> بالعدد <code>n</code>. داخل النمط استخدم المؤشر  ‎<code>\n</code>، أما خارج النمط فاستخدم <code>MatchData[n]‎</code>.
 
يمكن استخدام الأقواس لأجل الالتقاط (capturing). ويمكن لاحقًا التأشير إلى النص المتضمن في مجموعة الأقواس رقم <code>n</code> بالعدد <code>n</code>. داخل النمط استخدم المؤشر  ‎<code>\n</code>، أما خارج النمط فاستخدم <code>MatchData[n]‎</code>.
  
في المثال أدناه، تلتقط "<code>at</code>" بالزوج الأول من الأقواس، ثم يتم التأشير إليها باستخدام ‎<code>\1</code>:
+
في المثال أدناه، تلتقط "<code>at</code>" بالزوج الأول من الأقواس، ثم يتم التأشير إليها باستخدام ‎<code>\1</code>:<syntaxhighlight lang="ruby">/[csh](..) [csh]\1 in/.match("The cat sat in the hat")
<syntaxhighlight lang="ruby">/[csh](..) [csh]\1 in/.match("The cat sat in the hat")
+
   #=> #<MatchData "cat sat in" 1:"at"></syntaxhighlight>يعيد التابع <code>[[Ruby/Regexp/match|match]]</code> كائنًا من النوع <code>[[Ruby/MatchData|MatchData]]</code>، والذي يجعل النص الذي تم التقاطه متاحًا عبر معامل الفهرسة <code>[]</code>:<syntaxhighlight lang="ruby">/[csh](..) [csh]\1 in/.match("The cat sat in the hat")[1] #=> 'at'</syntaxhighlight>يمكن التأشير إلى المجموعات الملتقطة باسمها الذي عُرّفت به في حال تعريفها وفق الصياغة <code>(?<</code>name<code>>)</code> أو <code>(?'</code>name<code>')</code>.<syntaxhighlight lang="ruby">/\$(?<dollars>\d+)\.(?<cents>\d+)/.match("$3.67")
   #=> #<MatchData "cat sat in" 1:"at"></syntaxhighlight>
 
يعيد التابع <code>[[Ruby/Regexp/match|match]]</code> كائنًا من النوع <code>[[Ruby/MatchData|MatchData]]</code>، والذي يجعل النص الذي تم التقاطه متاحًا عبر معامل الفهرسة <code>[]</code>:  
 
<syntaxhighlight lang="ruby">/[csh](..) [csh]\1 in/.match("The cat sat in the hat")[1] #=> 'at'</syntaxhighlight>
 
يمكن التأشير إلى المجموعات الملتقطة باسمها الذي عُرّفت به في حال تعريفها وفق الصياغة <code>(?<</code>name<code>>)</code> أو <code>(?'</code>name<code>')</code>.  
 
<syntaxhighlight lang="ruby">/\$(?<dollars>\d+)\.(?<cents>\d+)/.match("$3.67")
 
 
   #=> #<MatchData "$3.67" dollars:"3" cents:"67">
 
   #=> #<MatchData "$3.67" dollars:"3" cents:"67">
/\$(?<dollars>\d+)\.(?<cents>\d+)/.match("$3.67")[:dollars] #=> "3"</syntaxhighlight>
+
/\$(?<dollars>\d+)\.(?<cents>\d+)/.match("$3.67")[:dollars] #=> "3"</syntaxhighlight>يمكن التأشير إلى المجموعات المُسماة بواسطة ‎<code>\k<</code>name<code>>‎</code>، حيث <code>name</code> هو اسم المجموعة.<syntaxhighlight lang="ruby">/(?<vowel>[aeiou]).\k<vowel>.\k<vowel>/.match('ototomy')
يمكن التأشير إلى المجموعات المُسماة بواسطة ‎<code>\k<</code>name<code>>‎</code>، حيث <code>name</code> هو اسم المجموعة.  
+
   #=> #<MatchData "ototo" vowel:"o"></syntaxhighlight>'''ملاحظة''': لا يمكن للتعبير النمطي استخدام المؤشرات المسماة (named backreferences) والمؤشرات الرقمية (numbered backreferences) في وقت واحد. عند استخدام مجموعات الالتقاط المسماة (named capture groups) مع تعبير نمطي حرفي على الجانب الأيسر من التعبير والمعامل ‎<code>[[Ruby/Regexp/3D~|=~‎]]</code>، فسيتم تخزين النص الذي تم التقاطه في متغيرات محلية تحمل أسماء مشابهة.<syntaxhighlight lang="ruby">/\$(?<dollars>\d+)\.(?<cents>\d+)/ =~ "$3.67" #=> 0
<syntaxhighlight lang="ruby">/(?<vowel>[aeiou]).\k<vowel>.\k<vowel>/.match('ototomy')
 
   #=> #<MatchData "ototo" vowel:"o"></syntaxhighlight>
 
'''ملاحظة''': لا يمكن للتعبير النمطي استخدام المؤشرات المسماة (named backreferences) والمؤشرات الرقمية (numbered backreferences) في وقت واحد. عند استخدام مجموعات الالتقاط المسماة (named capture groups) مع تعبير نمطي حرفي على الجانب الأيسر من التعبير والمعامل ‎<code>[[Ruby/Regexp/3D~|=~‎]]</code>، فسيتم تخزين النص الذي تم التقاطه في متغيرات محلية تحمل أسماء مشابهة.  
 
<syntaxhighlight lang="ruby">/\$(?<dollars>\d+)\.(?<cents>\d+)/ =~ "$3.67" #=> 0
 
 
dollars #=> "3"</syntaxhighlight>
 
dollars #=> "3"</syntaxhighlight>
 +
==التجميع (Grouping)==
 +
تُجمّع (''group'') الأقواس التعابير التي تُطوّقها، مما يسمح بتحديدها كمجموعة واحدة. يتطابق النمط أدناه مع حرف متحرك (vowel) متبوع بحرفي كلمة (word characters):<syntaxhighlight lang="ruby">/[aeiou]\w{2}/.match("Caenorhabditis elegans") #=> #<MatchData "aen"></syntaxhighlight>بينما يتطابق النمط التالي مع حرف متحرك يتبعه حرف كلمة، مرتين ، أي‎<code>[aeiou]\w[aeiou]\w</code>: ‏"enor".<syntaxhighlight lang="ruby">/([aeiou]\w){2}/.match("Caenorhabditis elegans")
 +
  #=> #<MatchData "enor" 1:"or"></syntaxhighlight>يتيح التعبير <code>(‎?:…‎)</code> إمكانية التجميع، لكن بدون التقاط. هذا يعني أنه يُجمّع التعابير التي يحتوي عليها في وحدة غير قابلة للتجزيئ (atom) دون إنشاء مؤشر إليها (backreference). هذا يفيد في تحسين الأداء، لكن على حساب إضرار طفيف بقابلية القراءة.
  
== التجميع (Grouping) ==
+
في المثال أدناه، الزوج الأول من الأقواس يلتقط "<code>n</code>"، أما الثاني فيلتقط "<code>ti</code>". تتم الإشارة إلى المجموعة الثانية لاحقًا باستخدام المؤشر ‎<code>\2</code>:<syntaxhighlight lang="ruby">/I(n)ves(ti)ga\2ons/.match("Investigations")
تُجمّع (''group'') الأقواس التعابير التي تُطوّقها، مما يسمح بتحديدها كمجموعة واحدة. يتطابق النمط أدناه مع حرف متحرك (vowel) متبوع بحرفي كلمة (word characters):
+
   #=> #<MatchData "Investigations" 1:"n" 2:"ti"></syntaxhighlight>لقط أصبح الزوج الأول من الأقواس غير قابل للالتقاط بسبب استخدام ‎<code>?:‎</code>، لذلك قسيتطابق مع "<code>n</code>"، ولكنه لن ينشئ مؤشرًا إليه. وبالتالي ، فالمؤشر ‎<code>\1</code> يشير الآن إلى "<code>ti</code>".<syntaxhighlight lang="ruby">/I(?:n)ves(ti)ga\1ons/.match("Investigations")
<syntaxhighlight lang="ruby">/[aeiou]\w{2}/.match("Caenorhabditis elegans") #=> #<MatchData "aen"></syntaxhighlight>
 
بينما يتطابق النمط التالي مع حرف متحرك يتبعه حرف كلمة، مرتين ، أي‎<code>[aeiou]\w[aeiou]\w</code>: ‏"enor".
 
<syntaxhighlight lang="ruby">/([aeiou]\w){2}/.match("Caenorhabditis elegans")
 
  #=> #<MatchData "enor" 1:"or"></syntaxhighlight>
 
يتيح التعبير <code>(‎?:…‎)</code> إمكانية التجميع، لكن بدون التقاط. هذا يعني أنه يُجمّع التعابير التي يحتوي عليها في وحدة غير قابلة للتجزيئ (atom) دون إنشاء مؤشر إليها (backreference). هذا يفيد في تحسين الأداء، لكن على حساب إضرار طفيف بقابلية القراءة. 
 
 
 
في المثال أدناه، الزوج الأول من الأقواس يلتقط "<code>n</code>"، أما الثاني فيلتقط "<code>ti</code>". تتم الإشارة إلى المجموعة الثانية لاحقًا باستخدام المؤشر ‎<code>\2</code>:  
 
<syntaxhighlight lang="ruby">/I(n)ves(ti)ga\2ons/.match("Investigations")
 
   #=> #<MatchData "Investigations" 1:"n" 2:"ti"></syntaxhighlight>
 
لقط أصبح الزوج الأول من الأقواس غير قابل للالتقاط بسبب استخدام ‎<code>?:‎</code>، لذلك قسيتطابق مع "<code>n</code>"، ولكنه لن ينشئ مؤشرًا إليه. وبالتالي ، فالمؤشر ‎<code>\1</code> يشير الآن إلى "<code>ti</code>".  
 
<syntaxhighlight lang="ruby">/I(?:n)ves(ti)ga\1ons/.match("Investigations")
 
 
   #=> #<MatchData "Investigations" 1:"ti"></syntaxhighlight>
 
   #=> #<MatchData "Investigations" 1:"ti"></syntaxhighlight>
 +
==التجميع الذري (Atomic Grouping)==
 +
يمكن جعل التجميعات ذرية بواسطة التعبير <code>(‎?>pat)</code>. هذا سيؤدي إلى مطابقة التعبير الجزئي (subexpression) بشكل مستقل عن بقية التعبير، بحيث أنّ ما يطابقه سيصبح ثابتًا لبقية المطابقة، ما لم يتم التخلي عن التعبير الجزئي بأكمله وإعادة النظر فيه لاحقًا. بهذه الطريقة، تعامل <code>pat</code> باعتبارها وحدة غير قابلة للتجزيئ (ذرة).
  
== التجميع الذري (Atomic Grouping) ==
+
يتم استخدام التجميع الذري عادة لتحسين أداء الأنماط، وكذلك لمنع إنشاء مؤشرات (backtracking) بدون داعٍ.
يمكن جعل التجميعات ذرية بواسطة التعبير <code>(‎?>pat)</code>. هذا سيؤدي إلى مطابقة التعبير الجزئي (subexpression) بشكل مستقل عن بقية التعبير، بحيث أنّ ما يطابقه سيصبح ثابتًا لبقية المطابقة، ما لم يتم التخلي عن التعبير الجزئي بأكمله وإعادة النظر فيه لاحقًا. بهذه الطريقة، تعامل <code>pat</code> باعتبارها وحدة غير قابلة للتجزيئ (ذرة).  
 
  
يتم استخدام التجميع الذري عادة لتحسين أداء الأنماط، وكذلك لمنع إنشاء مؤشرات (backtracking) بدون داعٍ.  
+
يتطابق <code>"</code> في النمط أدناه مع الحرف الأول من السلسلة النصية، ثم يُطابق ‎<code>.*‎</code> علامة التنصيص <code>"</code>. يؤدي هذا إلى فشل المطابقة الإجمالية، وهكذا فالنص المطابق لـ ‎<code>.*‎</code> يُؤشّر إليه (backtracked) بموضع واحد، مما يجعل الحرف النهائي للسلسلة النصية متاحًا لمطابقة <code>"</code><syntaxhighlight lang="ruby">/".*"/.match('"Quote"')    #=> #<MatchData "\"Quote\""></syntaxhighlight>إذا تم تجميع ‎<code>.*‎</code> ذريًا، فسيرفض إنشاء مرجع للعلامة <code>"</code>، على الرغم من أنّ هذا سيعني أن المطابقة الإجمالية ستفشل<syntaxhighlight lang="ruby">/"(?>.*)"/.match('"Quote"') #=> nil</syntaxhighlight>
 +
==استدعاء التعابير الجزئية (Subexpression Calls)==
 +
تطابق الصياغة <code>‎\g<name>‎</code> التعبير الجزئي السابق المسمى <code>name</code>، والذي يمكن أن يكون اسم مجموعة أو رقم. هذا مُختلف عن التأشير في كونه يعيد معالجة المجموعة بدلاً من مجرد محاولة إعادة مطابقة نفس النص.
  
يتطابق <code>"</code> في النمط أدناه مع الحرف الأول من السلسلة النصية، ثم يُطابق ‎<code>.*‎</code> علامة التنصيص <code>"</code>. يؤدي هذا إلى فشل المطابقة الإجمالية، وهكذا فالنص المطابق لـ ‎<code>.*‎</code> يُؤشّر إليه (backtracked) بموضع واحد، مما يجعل الحرف النهائي للسلسلة النصية متاحًا لمطابقة <code>"</code>
+
يتطابق النمط التالي مع الحرف <code>(</code>ويُحيله إلى المجموعة <code>paren</code>، ويحاول استدعاء التعبير الجزئي للمجموعة <code>paren</code> مرة أخرى، لكنه يفشل، ثم يطابق الحرف <code>)</code>:<syntaxhighlight lang="ruby">/\A(?<paren>\(\g<paren>*\))*\z/ =~ '()'
<syntaxhighlight lang="ruby">/".*"/.match('"Quote"')    #=> #<MatchData "\"Quote\""></syntaxhighlight>
 
إذا تم تجميع ‎<code>.*‎</code> ذريًا، فسيرفض إنشاء مرجع للعلامة <code>"</code>، على الرغم من أنّ هذا سيعني أن المطابقة الإجمالية ستفشل
 
<syntaxhighlight lang="ruby">/"(?>.*)"/.match('"Quote"') #=> nil</syntaxhighlight>
 
 
 
== استدعاء التعابير الجزئية (Subexpression Calls) ==
 
تطابق الصياغة <code>‎\g<name>‎</code> التعبير الجزئي السابق المسمى <code>name</code>، والذي يمكن أن يكون اسم مجموعة أو رقم. هذا مُختلف عن التأشير في كونه يعيد معالجة المجموعة بدلاً من مجرد محاولة إعادة مطابقة نفس النص. 
 
 
 
يتطابق النمط التالي مع الحرف <code>(</code>ويُحيله إلى المجموعة <code>paren</code>، ويحاول استدعاء التعبير الجزئي للمجموعة <code>paren</code> مرة أخرى، لكنه يفشل، ثم يطابق الحرف <code>)</code>:  
 
<syntaxhighlight lang="ruby">/\A(?<paren>\(\g<paren>*\))*\z/ =~ '()'
 
 
/\A(?<paren>\(\g<paren>*\))*\z/ =~ '(())' #=> 0
 
/\A(?<paren>\(\g<paren>*\))*\z/ =~ '(())' #=> 0
 
# ^1
 
# ^1
سطر 153: سطر 119:
 
#                      ^9
 
#                      ^9
 
#                          ^10</syntaxhighlight>
 
#                          ^10</syntaxhighlight>
# يطابق بداية السلسلة النصية، أي قبل الحرف الأول.
+
#يطابق بداية السلسلة النصية، أي قبل الحرف الأول.
# يدخل مجموعة التقاط مسماة (named capture group) تحمل الاسم<code>paren</code>  
+
#يدخل مجموعة التقاط مسماة (named capture group) تحمل الاسم<code>paren</code>
# يطابق المحرف <code>(</code>، الحرف الأول في السلسلة النصية  
+
#يطابق المحرف <code>(</code>، الحرف الأول في السلسلة النصية
# يستدعي المجموعة <code>paren</code> مرة أخرى، أي يعاود الرجوع (recurses) مرة أخرى إلى الخطوة الثانية  
+
#يستدعي المجموعة <code>paren</code> مرة أخرى، أي يعاود الرجوع (recurses) مرة أخرى إلى الخطوة الثانية
# يعيد الدخول إلى المجموعة <code>paren</code>  
+
#يعيد الدخول إلى المجموعة <code>paren</code>
# يطابق المحرف <code>(</code>، الحرف الثاني في السلسلة النصية  
+
#يطابق المحرف <code>(</code>، الحرف الثاني في السلسلة النصية
# يحاول استدعاء <code>paren</code> للمرة الثالثة، ولكن يفشله، لأن ذلك من شأنه أن يمنع مطابقة ناجحة شاملة  
+
#يحاول استدعاء <code>paren</code> للمرة الثالثة، ولكن يفشله، لأن ذلك من شأنه أن يمنع مطابقة ناجحة شاملة
# يطابق المحرف <code>)</code>، أي الحرف الثالث في السلسلة النصية.  
+
#يطابق المحرف <code>)</code>، أي الحرف الثالث في السلسلة النصية.
# يحدد نهاية الاستدعاء العودي (recursive) الثاني  
+
#يحدد نهاية الاستدعاء العودي (recursive) الثاني
# يطابق المحرف <code>)</code>، الحرف الرابع في السلسلة النصية  
+
#يطابق المحرف <code>)</code>، الحرف الرابع في السلسلة النصية
# يطابق نهاية السلسلة النصية  
+
#يطابق نهاية السلسلة النصية
 
+
==البدائل (Alternation)==
== البدائل (Alternation) ==
 
 
يُؤلّف الحرف الخاص (<code>|</code>) بين تعبيرين في تعبير واحد يطابق أيًا من '''ذَيْنِكَ''' التعبيرين. فكل تعبير هو بديل ممكن.<syntaxhighlight lang="ruby">/\w(and|or)\w/.match("Feliformia") #=> #<MatchData "form" 1:"or">
 
يُؤلّف الحرف الخاص (<code>|</code>) بين تعبيرين في تعبير واحد يطابق أيًا من '''ذَيْنِكَ''' التعبيرين. فكل تعبير هو بديل ممكن.<syntaxhighlight lang="ruby">/\w(and|or)\w/.match("Feliformia") #=> #<MatchData "form" 1:"or">
 
/\w(and|or)\w/.match("furandi")    #=> #<MatchData "randi" 1:"and">
 
/\w(and|or)\w/.match("furandi")    #=> #<MatchData "randi" 1:"and">
 
/\w(and|or)\w/.match("dissemblance") #=> nil</syntaxhighlight>
 
/\w(and|or)\w/.match("dissemblance") #=> nil</syntaxhighlight>
 
+
==خاصيات الحروف (Character Properties)==
== خاصيات الحروف (Character Properties) ==
+
تُطابق الصياغة ‎<code>\p{}‎</code> الحروف ذات الخاصية المعطاة، وهي مشابهة لمجموعات أقواس POSIX.
تُطابق الصياغة ‎<code>\p{}‎</code> الحروف ذات الخاصية المعطاة، وهي مشابهة لمجموعات أقواس POSIX.  
+
*<code>/p{Alnum}‎\/</code> - حرف أبجدي أو رقمي
* <code>/p{Alnum}‎\/</code> - حرف أبجدي أو رقمي
+
*<code>/p{Alpha}‎\/</code> - حرف أبجدي
* <code>/p{Alpha}‎\/</code> - حرف أبجدي
+
*<code>/p{Blank}‎\/</code> - مسافة بيضاء أو علامة تبويب (tab)
* <code>/p{Blank}‎\/</code> - مسافة بيضاء أو علامة تبويب (tab)
+
*<code>/p{Cntrl}‎\/</code> - محرف تحكم  (Control character)
* <code>/p{Cntrl}‎\/</code> - محرف تحكم  (Control character)  
+
*<code>/p{Digit}‎\/</code> - رقم
* <code>/p{Digit}‎\/</code> - رقم
+
*<code>/p{Graph}‎\/</code> - حرف غير فارغ (يستثني المسافات البيضاء وأحرف التحكم وما شابه)
* <code>/p{Graph}‎\/</code> - حرف غير فارغ (يستثني المسافات البيضاء وأحرف التحكم وما شابه)
+
*<code>/p{Lower}‎\/</code> - حرف أبجدي صغير
* <code>/p{Lower}‎\/</code> - حرف أبجدي صغير
+
*<code>/p{Print}\/</code> - مثل ‎<code>\p{Graph}‎</code> ، ولكنه يتضمن المسافة البيضاء
* <code>/p{Print}\/</code> - مثل ‎<code>\p{Graph}‎</code> ، ولكنه يتضمن المسافة البيضاء
+
*<code>/p{Punct}‎/</code> - علامة ترقيم
* <code>/p{Punct}‎/</code> - علامة ترقيم
+
*<code>/p{Space}‎\/</code> - حرف مسافة بيضاء (<code>[:blank:]</code> أو سطر جديد أو حرف إرجاع [carriage return]، إلخ)
* <code>/p{Space}‎\/</code> - حرف مسافة بيضاء (<code>[:blank:]</code> أو سطر جديد أو حرف إرجاع [carriage return]، إلخ)  
+
*<code>/p{Upper}‎\/</code> - حرف أبجدي كبير
* <code>/p{Upper}‎\/</code> - حرف أبجدي كبير
+
*<code>/p‎‎{XDigit}‎\/</code> - رقم من الأرقام المسموح بها في الأعداد السداسي عشرية (على سبيل المثال ، 0-9a-fA-F)
* <code>/p‎‎{XDigit}‎\/</code> - رقم من الأرقام المسموح بها في الأعداد السداسي عشرية (على سبيل المثال ، 0-9a-fA-F)
+
*<code>/p{Word}‎\/</code> - عنصر من إحدى مجموعات اليونيكود العامة التالية Letter، Mark، Number، Connector_Punctuation
* <code>/p{Word}‎\/</code> - عنصر من إحدى مجموعات اليونيكود العامة التالية Letter، Mark، Number، Connector_Punctuation  
+
*<code>/p{ASCII}‎\/</code> - حرف من حروف ASCII.
* <code>/p{ASCII}‎\/</code> - حرف من حروف ASCII.  
+
*<code>/p{Any}‎\/</code> - أي حرف من حروف اليونيكود (بما في ذلك الأحرف غير المعينة [unassigned]).
* <code>/p{Any}‎\/</code> - أي حرف من حروف اليونيكود (بما في ذلك الأحرف غير المعينة [unassigned]).  
+
*<code>/p{Assigned}‎\/</code> - حرف معين (assigned character).
* <code>/p{Assigned}‎\/</code> - حرف معين (assigned character).
+
يمكن أيضًا مطابقة حرف من مجموعة اليونيكود General Category بالنمط ‎<code>\p{</code>Ab<code>}‎</code> حيث Ab يمثل اختصار المجموعة كما هو موضح أدناه:<syntaxhighlight lang="ruby">
يمكن أيضًا مطابقة حرف من مجموعة اليونيكود General Category بالنمط ‎<code>\p{</code>Ab<code>}‎</code> حيث Ab يمثل اختصار المجموعة كما هو موضح أدناه:   <syntaxhighlight lang="ruby">
 
 
/\p{L}/ - 'Letter'
 
/\p{L}/ - 'Letter'
  
سطر 268: سطر 232:
  
  
</syntaxhighlight>في الأخير، تطابق ‎<code>\p{}‎</code> محارف خطوط اليونيكود، الخطوط التالية مدعومة:   <syntaxhighlight lang="ruby">
+
</syntaxhighlight>في الأخير، تطابق ‎<code>\p{}‎</code> محارف خطوط اليونيكود، الخطوط التالية مدعومة:<syntaxhighlight lang="ruby">
 
Arabic, Armenian, Balinese, Bengali, Bopomofo, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, Cham, Cherokee, Common, Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, Devanagari, Ethiopic, Georgian, Glagolitic, Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hiragana, Inherited, Kannada, Katakana, Kayah_Li, Kharoshthi, Khmer, Lao, Latin, Lepcha, Limbu, Linear_B, Lycian, Lydian, Malayalam, Mongolian, Myanmar, New_Tai_Lue, Nko, Ogham, Ol_Chiki, Old_Italic, Old_Persian, Oriya, Osmanya, Phags_Pa, Phoenician, Rejang, Runic, Saurashtra, Shavian, Sinhala, Sundanese, Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, Ugaritic, Vai, and Yi
 
Arabic, Armenian, Balinese, Bengali, Bopomofo, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, Cham, Cherokee, Common, Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, Devanagari, Ethiopic, Georgian, Glagolitic, Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hiragana, Inherited, Kannada, Katakana, Kayah_Li, Kharoshthi, Khmer, Lao, Latin, Lepcha, Limbu, Linear_B, Lycian, Lydian, Malayalam, Mongolian, Myanmar, New_Tai_Lue, Nko, Ogham, Ol_Chiki, Old_Italic, Old_Persian, Oriya, Osmanya, Phags_Pa, Phoenician, Rejang, Runic, Saurashtra, Shavian, Sinhala, Sundanese, Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, Ugaritic, Vai, and Yi
</syntaxhighlight>محرف اليونيكود <code>U+06E9</code> يُسمى "ARABIC PLACE of SAJDAH" (موضع سجدة)، وينتمي إلى الخط العربي: <syntaxhighlight lang="ruby">/\p{Arabic}/.match("\u06E9") #=> #<MatchData "\u06E9"></syntaxhighlight>
+
</syntaxhighlight>محرف اليونيكود <code>U+06E9</code> يُسمى "ARABIC PLACE of SAJDAH" (موضع سجدة)، وينتمي إلى الخط العربي:<syntaxhighlight lang="ruby">/\p{Arabic}/.match("\u06E9") #=> #<MatchData "\u06E9"></syntaxhighlight>يمكن عكس جميع خصائص الأحرف عن طريق إضافة البادئة (<code>^</code>) إلى أسمائها. الحرف "<code>A</code>" ليس مُتضمّنًا في مجموعة اليونيكود Ll [التي تعني (Letter; Lowercase)]، لذلك تنجح المطابقة التالية:<syntaxhighlight lang="ruby">/\p{^Ll}/.match("A") #=> #<MatchData "A"></syntaxhighlight>
يمكن عكس جميع خصائص الأحرف عن طريق إضافة البادئة (<code>^</code>) إلى أسمائها. الحرف "<code>A</code>" ليس مُتضمّنًا في مجموعة اليونيكود Ll [التي تعني (Letter; Lowercase)]، لذلك تنجح المطابقة التالية:  
+
==المراسي (Anchors)==
<syntaxhighlight lang="ruby">/\p{^Ll}/.match("A") #=> #<MatchData "A"></syntaxhighlight>
+
المراسي (Anchors) هي حروف خاصة تُطابق مواضع معدومة الطول بين الأحرف، وتربط المطابقة بموضع معين.
 
+
*<code>^</code> - تطابق بداية السطر
== المراسي (Anchors) ==
+
*<code>$</code> - تطابق نهاية السطر
المراسي (Anchors) هي حروف خاصة تُطابق مواضع معدومة الطول بين الأحرف، وتربط المطابقة بموضع معين.
+
*‎<code>\A</code> - تطابق بداية السلسلة النصية.
* <code>^</code> - تطابق بداية السطر
+
*‎<code>\Z</code> - تطابق نهاية السلسلة النصية. إذا انتهت السلسلة النصية بسطر جديد، فستُطابق الموضع الموجود قبل السطر الجديد مباشرة
* <code>$</code> - تطابق نهاية السطر
+
*‎<code>\z</code> - تطابق نهاية السلسلة النصية
* ‎<code>\A</code> - تطابق بداية السلسلة النصية.  
 
* ‎<code>\Z</code> - تطابق نهاية السلسلة النصية. إذا انتهت السلسلة النصية بسطر جديد، فستُطابق الموضع الموجود قبل السطر الجديد مباشرة
 
* ‎<code>\z</code> - تطابق نهاية السلسلة النصية
 
  
* <code>\G</code> - تطابق أول موضع مطابقة:  في توابع مثل <code>String#gsub</code> و <code>String#scan</code>، تتغير عند كل تكرار. حيث تتطابق في البداية مع بداية الموضوع، وفي كل تكرار تطابق مكان انتهاء المطابقة الأخيرة  
+
*<code>\G</code> - تطابق أول موضع مطابقة:  في توابع مثل <code>String#gsub</code> و <code>String#scan</code>، تتغير عند كل تكرار. حيث تتطابق في البداية مع بداية الموضوع، وفي كل تكرار تطابق مكان انتهاء المطابقة الأخيرة
 
<syntaxhighlight lang="ruby">"    a b c".gsub(/ /, '_')    #=> "____a_b_c"
 
<syntaxhighlight lang="ruby">"    a b c".gsub(/ /, '_')    #=> "____a_b_c"
 
"    a b c".gsub(/\G /, '_')  #=> "____a b c"
 
"    a b c".gsub(/\G /, '_')  #=> "____a b c"
 
‎</syntaxhighlight>في التوابع التي تأخذ موضعًا (اختياريًا)، مثل <code>[[Ruby/Regexp/match|Regexp#match]]</code> و <code>[[Ruby/String/match|String#match]]</code>، ستُطابق مكان بدء البحث.<syntaxhighlight lang="ruby">"hello, world".match(/,/, 3)    #=> #<MatchData ",">
 
‎</syntaxhighlight>في التوابع التي تأخذ موضعًا (اختياريًا)، مثل <code>[[Ruby/Regexp/match|Regexp#match]]</code> و <code>[[Ruby/String/match|String#match]]</code>، ستُطابق مكان بدء البحث.<syntaxhighlight lang="ruby">"hello, world".match(/,/, 3)    #=> #<MatchData ",">
 
"hello, world".match(/\G,/, 3)  #=> nil</syntaxhighlight>
 
"hello, world".match(/\G,/, 3)  #=> nil</syntaxhighlight>
* ‎<code>\b</code> - تطابق مواضع حدود الكلمات (word boundaries) عندما تكون خارج الأقواس؛ وتطابق محرف التراجع backspace‏ (0x08) عندما تكون داخل الأقواس
+
*‎<code>\b</code> - تطابق مواضع حدود الكلمات (word boundaries) عندما تكون خارج الأقواس؛ وتطابق محرف التراجع backspace‏ (0x08) عندما تكون داخل الأقواس
* ‎<code>\B</code> - تُطابق المواضع المخالفة لحدود الكلمات
+
*‎<code>\B</code> - تُطابق المواضع المخالفة لحدود الكلمات
* <code>(‎?=</code>pat<code>)</code> - المطالعة الأمامية الإيجابية (Positive lookahead assertion): تتأكد من أنّ الأحرف التالية تتطابق مع <code>pat</code>، ولكن لا تتضمن تلك الأحرف في النص المُطابق
+
*<code>(‎?=</code>pat<code>)</code> - المطالعة الأمامية الإيجابية (Positive lookahead assertion): تتأكد من أنّ الأحرف التالية تتطابق مع <code>pat</code>، ولكن لا تتضمن تلك الأحرف في النص المُطابق
* <code>(‎?!</code>pat<code>)</code> - المطالعة الأمامية السلبية (Negative lookahead assertion): تتأكد من أنّ الأحرف التالية لا تتطابق مع <code>pat</code>، ولكن لا تتضمن تلك الأحرف في النص المُطابق
+
*<code>(‎?!</code>pat<code>)</code> - المطالعة الأمامية السلبية (Negative lookahead assertion): تتأكد من أنّ الأحرف التالية لا تتطابق مع <code>pat</code>، ولكن لا تتضمن تلك الأحرف في النص المُطابق
* <code>(‎?<=</code>pat<code>)</code> -المطالعة الخلفية الإيجابية (Positive lookbehind assertion): تتأكد من تطابق الأحرف السابقة مع <code>pat</code>، ولكنها لا تتضمّن تلك الأحرف في النص المُطابق
+
*<code>(‎?<=</code>pat<code>)</code> -المطالعة الخلفية الإيجابية (Positive lookbehind assertion): تتأكد من تطابق الأحرف السابقة مع <code>pat</code>، ولكنها لا تتضمّن تلك الأحرف في النص المُطابق
* <code>(‎?<!</code>pat<code>)</code> - المطالعة الخلفية الإيجابية (Negative lookbehind assertion): تتأكد من أنّ الأحرف السابقة لا تتطابق مع <code>pat</code>، ولكنها لا تتضمن تلك الأحرف في النص المُطابق
+
*<code>(‎?<!</code>pat<code>)</code> - المطالعة الخلفية الإيجابية (Negative lookbehind assertion): تتأكد من أنّ الأحرف السابقة لا تتطابق مع <code>pat</code>، ولكنها لا تتضمن تلك الأحرف في النص المُطابق
إذا لم يتم وضع مرساة (anchor) للنمط، فيمكنه أن يبدأ من أي نقطة في السلسلة النصية:<syntaxhighlight lang="ruby">/real/.match("surrealist") #=> #<MatchData "real"></syntaxhighlight>
+
إذا لم يتم وضع مرساة (anchor) للنمط، فيمكنه أن يبدأ من أي نقطة في السلسلة النصية:<syntaxhighlight lang="ruby">/real/.match("surrealist") #=> #<MatchData "real"></syntaxhighlight>إرساء (Anchoring) النمط عند بداية السلسلة النصية يفرض بدء المطابقة هناك. في المثال الآتي، لا تظهر "<code>real</code>" في بداية السلسلة النصية، لذلك تفشل المطابقة:<syntaxhighlight lang="ruby">/\Areal/.match("surrealist") #=> nil</syntaxhighlight>تفشل المطابقة أدناه لأنه على الرغم من أن "<code>Demand</code>" تحتوي "<code>and</code>" ، فإنّ النمط لا يظهر عند حدود الكلمات (word boundary).<syntaxhighlight lang="ruby">/\band/.match("Demand")</syntaxhighlight>في حين أنّه في المثال التالي السلسلة النصية "<code>and</code>" تم إرساؤها عند المواضع المخالفة لحدود الكلمات (non-word boundary)، لذلك، فبدلاً من مطابقة "<code>and</code>" الأولى، فستتطابق مع الحرف الرابع من "<code>demand</code>" بدلاً من ذلك:<syntaxhighlight lang="ruby">/\Band.+/.match("Supply and demand curve") #=> #<MatchData "and curve"></syntaxhighlight>يستخدم النمط التالي المطالعة الأمامية الإيجابية و االمطالعة الخلفية الإيجابية لمطابقة النص الوارد في الوسوم (tags) دون تضمين الوسوم في المطابقة:<syntaxhighlight lang="ruby">/(?<=<b>)\w+(?=<\/b>)/.match("Fortune favours the <b>bold</b>")
إرساء (Anchoring) النمط عند بداية السلسلة النصية يفرض بدء المطابقة هناك. في المثال الآتي، لا تظهر "<code>real</code>" في بداية السلسلة النصية، لذلك تفشل المطابقة:  
 
<syntaxhighlight lang="ruby">/\Areal/.match("surrealist") #=> nil</syntaxhighlight>
 
تفشل المطابقة أدناه لأنه على الرغم من أن "<code>Demand</code>" تحتوي "<code>and</code>" ، فإنّ النمط لا يظهر عند حدود الكلمات (word boundary).  
 
<syntaxhighlight lang="ruby">/\band/.match("Demand")</syntaxhighlight>
 
في حين أنّه في المثال التالي السلسلة النصية "<code>and</code>" تم إرساؤها عند المواضع المخالفة لحدود الكلمات (non-word boundary)، لذلك، فبدلاً من مطابقة "<code>and</code>" الأولى، فستتطابق مع الحرف الرابع من "<code>demand</code>" بدلاً من ذلك:  
 
<syntaxhighlight lang="ruby">/\Band.+/.match("Supply and demand curve") #=> #<MatchData "and curve"></syntaxhighlight>
 
يستخدم النمط التالي المطالعة الأمامية الإيجابية و االمطالعة الخلفية الإيجابية لمطابقة النص الوارد في الوسوم (tags) دون تضمين الوسوم في المطابقة:  
 
<syntaxhighlight lang="ruby">/(?<=<b>)\w+(?=<\/b>)/.match("Fortune favours the <b>bold</b>")
 
 
   #=> #<MatchData "bold"></syntaxhighlight>
 
   #=> #<MatchData "bold"></syntaxhighlight>
 
+
==الخيارات==
== الخيارات ==
+
يمكن أن يُعقب محدد النهاية للتعبير النمطي بحرف واحد أو أكثر  يمثل الخيارات التي تتحكم في كيفية مطابقة النمط.
يمكن أن يُعقب محدد النهاية للتعبير النمطي بحرف واحد أو أكثر  يمثل الخيارات التي تتحكم في كيفية مطابقة النمط.
+
*‎<code>/pat/i</code> - يتجاهل حالة الأحرف
* ‎<code>/pat/i</code> - يتجاهل حالة الأحرف
+
*‎<code>/pat/m</code> - تجعل <code>.</code> تطابق محرف السطر الجديد
* ‎<code>/pat/m</code> - تجعل <code>.</code> تطابق محرف السطر الجديد
+
*‎<code>/pat/x</code> - تتجاهل المسافات البيضاء والتعليقات الموجودة في النمط
* ‎<code>/pat/x</code> - تتجاهل المسافات البيضاء والتعليقات الموجودة في النمط  
+
*‎<code>/pat/o</code> - تنفّذ عملية التلقيم‎<code>#{}‎</code> مرة واحدة فقط
* ‎<code>/pat/o</code> - تنفّذ عملية التلقيم‎<code>#{}‎</code> مرة واحدة فقط
+
يمكن أيضًا تطبيق الخيارات <code>i</code> و<code>m</code> و <code>x</code> على مستوى التعابير الجزئية (subexpression) عبر الصياغة <code>(‎?on-off)</code>، والتي تفعّل الخيارات <code>on</code>، وتعطّل الخيارات <code>off</code> في التعبير المحاط بالأقواس.<syntaxhighlight lang="ruby">/a(?i:b)c/.match('aBc') #=> #<MatchData "aBc">
يمكن أيضًا تطبيق الخيارات <code>i</code> و<code>m</code> و <code>x</code> على مستوى التعابير الجزئية (subexpression) عبر الصياغة <code>(‎?on-off)</code>، والتي تفعّل الخيارات <code>on</code>، وتعطّل الخيارات <code>off</code> في التعبير المحاط بالأقواس.  
 
<syntaxhighlight lang="ruby">/a(?i:b)c/.match('aBc') #=> #<MatchData "aBc">
 
 
/a(?i:b)c/.match('abc') #=> #<MatchData "abc">
 
/a(?i:b)c/.match('abc') #=> #<MatchData "abc">
‎</syntaxhighlight>
+
‎</syntaxhighlight>كما يمكن استخدام الخيارات مع التابع <code>[[Ruby/Regexp/new|new]]</code>:<syntaxhighlight lang="ruby">Regexp.new("abc", Regexp::IGNORECASE)                    #=> /abc/i
كما يمكن استخدام الخيارات مع التابع <code>[[Ruby/Regexp/new|new]]</code>:  
 
<syntaxhighlight lang="ruby">Regexp.new("abc", Regexp::IGNORECASE)                    #=> /abc/i
 
 
Regexp.new("abc", Regexp::MULTILINE)                      #=> /abc/m
 
Regexp.new("abc", Regexp::MULTILINE)                      #=> /abc/m
 
Regexp.new("abc # Comment", Regexp::EXTENDED)            #=> /abc # Comment/x
 
Regexp.new("abc # Comment", Regexp::EXTENDED)            #=> /abc # Comment/x
 
Regexp.new("abc", Regexp::IGNORECASE | Regexp::MULTILINE) #=> /abc/mi</syntaxhighlight>
 
Regexp.new("abc", Regexp::IGNORECASE | Regexp::MULTILINE) #=> /abc/mi</syntaxhighlight>
 +
==وضع التراص (Free-Spacing Mode) والتعليقات==
 +
كما ذُكر أعلاه، يتيح الخيار <code>x</code> وضع التراص (''free-spacing'' mode). حيث يتم تجاهل محارف المسافاة البيضاء (Literal white space) داخل النمط، ويقدم محرف الشباك octothorpe (<code>#</code>) تعليقًا يستمر إلى نهاية السطر. يسمح هذا بتنظيم مكونات النمط بطريقة تجعله أكثر مقروئية.
  
== وضع التراص (Free-Spacing Mode) والتعليقات ==
+
في المثال التالي يطابق النمط عددًا ذا منازل عشرية اختيارية:<syntaxhighlight lang="ruby">float_pat = /\A
كما ذُكر أعلاه، يتيح الخيار <code>x</code> وضع التباعد الحر. يتم تجاهل محارف المسافاة البيضاء داخل النمط، ويقدم محرف الشباك octothorpe (<code>#</code>) تعليقًا حتى نهاية السطر. يسمح هذا بتنظيم مكونات النمط بطريقة تجعله أكثر مقروئية. في المثال التالي يطابق النمط عددًا مع منازل عشرية اختيارية:  
 
<syntaxhighlight lang="ruby">float_pat = /\A
 
 
   [[:digit:]]+ # 1 or more digits before the decimal point
 
   [[:digit:]]+ # 1 or more digits before the decimal point
 
   (\.          # Decimal point
 
   (\.          # Decimal point
سطر 328: سطر 277:
 
   )? # The decimal point and following digits are optional
 
   )? # The decimal point and following digits are optional
 
\Z/x
 
\Z/x
float_pat.match('3.14') #=> #<MatchData "3.14" 1:".14">
+
float_pat.match('3.14') #=> #<MatchData "3.14" 1:".14"></syntaxhighlight>هناك عدة استراتيجيات لمطابقة المسافات البيضاء:
</syntaxhighlight>
+
* استخدام أنماط مثل <code>\s</code> أو <code>\p{Space‎}</code>.
هناك عدة استراتيجيات لمطابقة المسافات البيضاء: *استخدم نمطًا مثل <code>\s</code> أو <code>\p{Space}</code>. *استخدم مسافات بيضاء مُخلّصة (escaped whitespace) مثل <code>\</code>، أي مسافة مسبوقة بخط مائل عكسي. *استخدم مجموعة حروف مثل <code>[ ]</code>.   يمكن تضمين التعليقات في انماط غير النمط <code>x</code> باستخدام الصياغة <code>(?#</code>comment<code>)</code>، حيث أن التعليق نص اعتباطي يتم تجاهله من محرك التعبير النمطي. لا يمكن أن تتضمن التعليقات المُتضمّنة في تعبير نمطي حرفي محرف إنهاء غير مُخلص (unescaped terminator characters). <code>[[Ruby/Encoding|Encoding]]</code><code>[[Ruby//class-Regexp-label-Encoding|¶]]</code> <code>[[Ruby//top|↑]]</code> يفترض أن تستخدام التعابير النمطية ترميز المصدر. يمكن تجاوز هذا بأحد المُعدِّلات التالية. <code>/</code>pat<code>/u</code> - UTF-8 <code>/</code>pat<code>/e</code> - EUC-JP <code>/</code>pat<code>/s</code> - Windows-31J <code>/</code>pat<code>/n</code> - ASCII-8BIT يمكن مطابقة تعبير نمطي مع سلسلة نصية عندما يتشاركان في الترميز، أو إن كان ترميز التعبير النمطي هو US-ASCII وترميز السلسلة النصية متوافق مع ASCII. إذا تمت محاولة المطابقة بين ترميزات غير متوافقة، فسيُطلق الاستثناء <code>Encoding::CompatibilityError</code>. تتحقق الدالة المنطقية <code>Regexp#fixed_encoding?</code> مما إذا كان للتعبير النمطي ترميز ثابت، ومتوافق مع الترميز ASCII. يمكن تثبيت ترميز التعبير النمطي بشكل صريح عبر تمرير <code>Regexp::FIXEDENCODING</code> كوسيط ثانٍ للتابع <code>Regexp.new</code>:  
+
* استخدام مسافات بيضاء مُخلّصة (escaped whitespace) مثل " <code>\</code>"، أي مسافة مسبوقة بخط مائل عكسي.
<syntaxhighlight lang="ruby">r = Regexp.new("a".force_encoding("iso-8859-1"),Regexp::FIXEDENCODING)
+
* استخدام مجموعة حروف مثل <code>[ ]</code>.
 +
يمكن تضمين التعليقات في نمط لا يعتمد الخيار  ‏<code>x‏</code> (non-x pattern) باستخدام الصياغة <code>(?#comment)</code>، حيث يكون التعليق عبارة عن نص اعتباطي يتم تجاهله من محرك التعبير النمطي.
 +
 
 +
لا يمكن أن تتضمن التعليقات المُتضمّنة في تعبير نمطي حرفي محرف إنهاء غير مُخلص (unescaped terminator characters).
 +
 
 +
== الترميز <code>Encoding</code> ==
 +
يفترض أن تستخدم التعابير النمطية ترميز المصدر. يمكن تعديل هذا السلوط بأحد المُعدِّلات التالية.
 +
* ‎<code>/</code>''pat''<code>/u</code> يعني UTF-8
 +
* ‎<code>/</code>''pat''<code>/e</code> يعني EUC-JP
 +
* ‎<code>/</code>''pat''<code>/s</code> يعني Windows-31J
 +
* ‎<code>/</code>''pat''<code>/n</code>  يعني ASCII-8BIT
 +
يمكن مطابقة تعبير نمطي مع سلسلة نصية عندما يتشاركان في الترميز، أو إن كان ترميز التعبير النمطي هو US-ASCII، وترميز السلسلة النصية متوافق مع ASCII.
 +
 
 +
في حال محاولة المطابقة بين ترميزات غير متوافقة، فسيُطلق الاستثناء <code>[[Ruby/Encoding/CompatibilityError|Encoding::CompatibilityError]]</code>.
 +
 
 +
تتحقق الدالة المنطقية <code>[[Ruby/Regexp/fixed encoding-3F|fixed_encoding?]]‎</code> مما إذا كان للتعبير النمطي ترميز ثابت، ومتوافق مع الترميز ASCII.
 +
 
 +
يمكن تثبيت ترميز التعبير النمطي بشكل صريح عبر تمرير الثابتة <code>Regexp::[[Ruby/Regexp/FIXEDENCODING|FIXEDENCODING]]</code> كوسيط ثانٍ للتابع <code>Regexp.new</code>:<syntaxhighlight lang="ruby">r = Regexp.new("a".force_encoding("iso-8859-1"),Regexp::FIXEDENCODING)
 
r =~ "a\u3042"
 
r =~ "a\u3042"
 
   # raises Encoding::CompatibilityError: incompatible encoding regexp match
 
   # raises Encoding::CompatibilityError: incompatible encoding regexp match
   #        (ISO-8859-1 regexp with UTF-8 string)
+
   #        (ISO-8859-1 regexp with UTF-8 string)</syntaxhighlight>
</syntaxhighlight>
+
 
متغيرات عامة مخصوصة <code>[[Ruby//class-Regexp-label-Special+global+variables|¶]]</code> من المهم معرفة بعض المتغيرات العامة: *<code>[[Ruby//top|↑]]</code> تكافئ <code>$~</code>؛ *<code>[[Ruby/Regexp/last_match|::last_match]]</code> تحتوي كامل النص المتطابق؛ *<code>$&</code> تحتوي السلسلة النصية التي تسبق التطابق؛ *<code>$`</code> تحتوي السلسلة النصية التي تعقب التطابق؛ *<code>$'</code> و <code>$1</code> وهلم جرًا، تحتوي النص المُتطابق مع مجموعة الالتقاط الأولى، والثانية، وما إلى ذلك؛ *<code>$2</code> تحتوي آخر مجموعة مُلتقطة. مثال: <code>$+</code> هذه المتغيرات العامة هي متغيرات مخصوصة بالمهام الفرعية (thread-local)، ومخصوصة بالتوابع (method-local). الأداء
+
== متغيرات عامة مخصوصة (Special global variables) ==
<syntaxhighlight lang="ruby">m = /s(\w{2}).*(c)/.match('haystack') #=> #<MatchData "stac" 1:"ta" 2:"c">
+
من المهم معرفة بعض المتغيرات العامة:
 +
* <code>$~</code>؛ تكافئ <code>[[Ruby/Regexp/last match|last_match]]</code>
 +
* ‎<code>$&‎</code> تحتوي كامل النص المتطابق؛
 +
* <code>$`‎</code>تحتوي السلسلة النصية التي تسبق التطابق
 +
* <code>$'‎</code> تحتوي السلسلة النصية التي تعقب التطابق؛
 +
* <code>$1‎‎</code> و <code>$2</code> ...، تحتوي النص المُتطابق مع مجموعة الالتقاط الأولى، والثانية، ...؛
 +
* <code>$+‎</code> تحتوي آخر مجموعة مُلتقطة.
 +
'''مثال''':<syntaxhighlight lang="ruby">m = /s(\w{2}).*(c)/.match('haystack') #=> #<MatchData "stac" 1:"ta" 2:"c">
 
$~                                    #=> #<MatchData "stac" 1:"ta" 2:"c">
 
$~                                    #=> #<MatchData "stac" 1:"ta" 2:"c">
 
Regexp.last_match                    #=> #<MatchData "stac" 1:"ta" 2:"c">
 
Regexp.last_match                    #=> #<MatchData "stac" 1:"ta" 2:"c">
سطر 354: سطر 327:
 
$+      #=> "c"
 
$+      #=> "c"
 
       # same as m[-1]
 
       # same as m[-1]
‎</syntaxhighlight>
+
‎</syntaxhighlight>هذه المتغيرات العامة هي متغيرات مخصوصة بالمهام الفرعية (thread-local)، ومخصوصة بالتوابع (method-local).
<code>[[Ruby//class-Regexp-label-Performance|¶]]</code> يمكن أن تؤدي بعض التوليفات غير السليمة في الصياغة إلى أداء سيئ جدا. انظر المثال التالي: <code>[[Ruby//top|↑]]</code> تتم مطابقة الأنماط التالية على الفور كما هو متوقع:
+
 
<syntaxhighlight lang="ruby">s = 'a' * 25 + 'd' + 'a' * 4 + 'c'
+
== الأداء (Performance) ==
#=> "aaaaaaaaaaaaaaaaaaaaaaaaadaaaac"
+
يمكن أن تؤدي بعض التوليفات غير السليمة في الصياغة إلى أداء سيئ جدا.
</syntaxhighlight>
+
 
أما النمط التالي فيستغرق وقتًا أطول بشكل ملحوظ:  
+
انظر المثال التالي:<syntaxhighlight lang="ruby">s = 'a' * 25 + 'd' + 'a' * 4 + 'c'
<syntaxhighlight lang="ruby">/(b|a)/ =~ s #=> 0
+
#=> "aaaaaaaaaaaaaaaaaaaaaaaaadaaaac"</syntaxhighlight>تتم مطابقة الأنماط التالية على الفور كما هو متوقع:<syntaxhighlight lang="ruby">/(b|a)/ =~ s #=> 0
 
/(b|a+)/ =~ s #=> 0
 
/(b|a+)/ =~ s #=> 0
 
/(b|a+)*/ =~ s #=> 0
 
/(b|a+)*/ =~ s #=> 0
‎</syntaxhighlight>
+
‎</syntaxhighlight>أما النمط التالي فيستغرق وقتًا أطول بشكل ملحوظ:<syntaxhighlight lang="ruby">/(b|a+)*c/ =~ s #=> 26
يحدث هذا لأن ذرة في التعبير النمطي مٌكمّمة (quantified) بواسطة كل من الحرف
+
‎</syntaxhighlight>يحدث هذا لأن ذرة (وحدة غير قابلة للتجزئي) في التعبير النمطي مٌكمّمة (quantified) بواسطة كل من الحرف <code>+</code> والحرف   <code>*</code>بدون تحديد لمن منهما سيكون التحكم لرحف معين. عدم الوضوح ينتج عنه ينتج أداء خطي فائق (super-linear performance). (راجع Mastering Regular Expressions (3rd ed.)، pp 222 ، بواسطة Jeffery Friedl ، لإجراء تحليل متعمق). يمكن إصلاح هذه المشكلة عن طريق استخدام التجميع الذري، والذي يمنع التأشير غير الضروري: يوضح المثال التالي حالة مشابهة، والتي استغرقت حوالي 60 ثانية للتنفيذ عندي: مطابقة سلسلة نصية مكونة 29 حرف "a" مقابل نمط مؤلف من 29 حرف "a" اختياري يليه 29 إلزاميًا على النحو التالي:<syntaxhighlight lang="ruby">(start = Time.now) && /(b|a+)*c/ =~ s && (Time.now - start)
<syntaxhighlight lang="ruby">/(b|a+)*c/ =~ s #=> 26
 
‎</syntaxhighlight>
 
والحرف <code>+</code> بدون تحديد لمن منهما سيكون التحكم لرحف معين. عدم الوضوح ينتج عنه ينتج أداء خطي فائق (super-linear performance). (راجع Mastering Regular Expressions (3rd ed.)، pp 222 ، بواسطة Jeffery Friedl ، لإجراء تحليل متعمق). يمكن إصلاح هذه المشكلة عن طريق استخدام التجميع الذري، والذي يمنع التأشير غير الضروري: <code>*</code> يوضح المثال التالي حالة مشابهة، والتي استغرقت حوالي 60 ثانية للتنفيذ عندي: مطابقة سلسلة نصية مكونة 29 حرف "a" مقابل نمط مؤلف من 29 حرف "a" اختياري يليه 29 إلزاميًا على النحو التالي:  
 
<syntaxhighlight lang="ruby">(start = Time.now) && /(b|a+)*c/ =~ s && (Time.now - start)
 
 
   #=> 24.702736882
 
   #=> 24.702736882
 
(start = Time.now) && /(?>b|a+)*c/ =~ s && (Time.now - start)
 
(start = Time.now) && /(?>b|a+)*c/ =~ s && (Time.now - start)
 
   #=> 0.000166571
 
   #=> 0.000166571
 +
‎</syntaxhighlight>حروف "a" التسعة وعشرون الاختيارية تطابق السلسلة النصية، لكن هذا يمنع الحروف التسعة وعشروت الإلزامية الموالية من المطابقة. تتراجع روبي مرارًا وتكرارًا حتى تستوفي أكبر عدد ممكن من التطابقات الاختيارية دون التفريط في المطابقة التسعة وعشرين الإجبارية. من الواضح لنا أنه لا يمكن لأي من المطابقات الاختيارية أن تنجح، ولكن هذه الحقيقة ليست واضحة للأسف لروبي. أفضل طريقة لتحسين الأداء هي تقليل مقدار التراجع المطلوب إلى أقصى حد.  في هذه الحالة، بدلاً من المطابقة الفردية لـ 29 حرفًا اختياريًا، يمكن مطابقة مجال اختياريً دفعة واحدة عبر {0،29}:<syntaxhighlight lang="ruby">Regexp.new('a?' * 29 + 'a' * 29) =~ 'a' * 29
 
‎</syntaxhighlight>
 
‎</syntaxhighlight>
حروف "a" التسعة وعشرون الاختيارية تطابق السلسلة النصية، لكن هذا يمنع الحروف التسعة وعشروت الإلزامية الموالية من المطابقة. تتراجع روبي مرارًا وتكرارًا حتى تستوفي أكبر عدد ممكن من التطابقات الاختيارية دون التفريط في المطابقة التسعة وعشرين الإجبارية. من الواضح لنا أنه لا يمكن لأي من المطابقات الاختيارية أن تنجح، ولكن هذه الحقيقة ليست واضحة للأسف لروبي. أفضل طريقة لتحسين الأداء هي تقليل مقدار التراجع المطلوب إلى أقصى حد.  في هذه الحالة، بدلاً من المطابقة الفردية لـ 29 حرفًا اختياريًا، يمكن مطابقة مجال اختياريً دفعة واحدة عبر {0،29}:
 
<syntaxhighlight lang="ruby">Regexp.new('a?' * 29 + 'a' * 29) =~ 'a' * 29
 
‎</syntaxhighlight>
 
 
 
 
==توابع الصنف العامة (Public Class Methods)==
 
==توابع الصنف العامة (Public Class Methods)==
===[[Ruby/Regexp/compile | التابع compile]]===
+
===[[Ruby/Regexp/compile| التابع compile]]===
 
اسم آخر للتابع <code>Regexp.new</code>
 
اسم آخر للتابع <code>Regexp.new</code>
===[[Ruby/Regexp/escape | التابع escape]]===
+
===[[Ruby/Regexp/escape| التابع escape]]===
 
يُخلّص (Escapes)  أي حرف يمكن أن يكون له معنى خاص في التعبير النمطي. ثم يعيد سلسلة نصية جديدة مُخلّصة، أو يعيد الكائن  (self) في حال عدم تخليص أي أحرف.  لكل سلسلة نصية str، ستكون قيمة <code>Regexp.new(Regexp.escape( str ))=~ str</code> مساوية للقيمة true.
 
يُخلّص (Escapes)  أي حرف يمكن أن يكون له معنى خاص في التعبير النمطي. ثم يعيد سلسلة نصية جديدة مُخلّصة، أو يعيد الكائن  (self) في حال عدم تخليص أي أحرف.  لكل سلسلة نصية str، ستكون قيمة <code>Regexp.new(Regexp.escape( str ))=~ str</code> مساوية للقيمة true.
===[[Ruby/Regexp/last_match | التابع last_match]]===
+
===[[Ruby/Regexp/last match| التابع last_match]]===
 
يُعيد  في الشكل الأول  كائن <code>[[Ruby/MatchData|MatchData]]</code> الذي تم إنشاؤه من آخر تطابق ناجح للنمط.  وهو مكافئ لقراءة المتغير العام المخصوص <code>$~</code> (راجع المتغيرات العامة المخصوصة في صفحة <code>[[Ruby/Regexp|Regexp]]</code> لمزيد من التفاصيل).
 
يُعيد  في الشكل الأول  كائن <code>[[Ruby/MatchData|MatchData]]</code> الذي تم إنشاؤه من آخر تطابق ناجح للنمط.  وهو مكافئ لقراءة المتغير العام المخصوص <code>$~</code> (راجع المتغيرات العامة المخصوصة في صفحة <code>[[Ruby/Regexp|Regexp]]</code> لمزيد من التفاصيل).
===[[Ruby/Regexp/new | التابع new]]===
+
===[[Ruby/Regexp/new| التابع new]]===
 
ينشئ  تعبيرًا نمطيًا جديدًا من <code>pattern</code>، والذي يمكن أن يكون إما سلسلة نصية (<code>[[Ruby/String|String]]</code>) أو كائنًا من النوع <code>[[Ruby/Regexp|Regexp]]</code> (وفي هذه الحالة يتم نشر خيارات التعبير النمطي)، وقد لا يتم تحديد خيارات جديدة (منذ روبي 1.8).
 
ينشئ  تعبيرًا نمطيًا جديدًا من <code>pattern</code>، والذي يمكن أن يكون إما سلسلة نصية (<code>[[Ruby/String|String]]</code>) أو كائنًا من النوع <code>[[Ruby/Regexp|Regexp]]</code> (وفي هذه الحالة يتم نشر خيارات التعبير النمطي)، وقد لا يتم تحديد خيارات جديدة (منذ روبي 1.8).
===[[Ruby/Regexp/quote | التابع quote]]===
+
===[[Ruby/Regexp/quote| التابع quote]]===
 
يُخلّص (escapes)  أي حرف قد يكون له معنى خاص في التعبير النمطي. ثم يُعيد سلسلة نصية جديدة مُخلّصة، أو يعيد الكائن  (self) إذا لم يتم تخليص أي أحرف.  لكل سلسلة نصية str، ستكون قيمة التعبير <code>Regexp.new(Regexp.escape( str ))=~ str</code> مساوية للقيمة true.
 
يُخلّص (escapes)  أي حرف قد يكون له معنى خاص في التعبير النمطي. ثم يُعيد سلسلة نصية جديدة مُخلّصة، أو يعيد الكائن  (self) إذا لم يتم تخليص أي أحرف.  لكل سلسلة نصية str، ستكون قيمة التعبير <code>Regexp.new(Regexp.escape( str ))=~ str</code> مساوية للقيمة true.
===[[Ruby/Regexp/try_convert | التابع try_convert]]===
+
===[[Ruby/Regexp/try convert| التابع try_convert]]===
 
يُحاول  تحويل الوسيط obj  إلى كائن من النوع <code>[[Ruby/Regexp|Regexp]]</code>، باستخدام التابع to_regexp. ثم يعيد التعبير النمطي الناتج، أو nil في حالة تعذر تحويل obj لسبب أو لآخر.
 
يُحاول  تحويل الوسيط obj  إلى كائن من النوع <code>[[Ruby/Regexp|Regexp]]</code>، باستخدام التابع to_regexp. ثم يعيد التعبير النمطي الناتج، أو nil في حالة تعذر تحويل obj لسبب أو لآخر.
===[[Ruby/Regexp/union | التابع union]]===
+
===[[Ruby/Regexp/union| التابع union]]===
 
يُعيد  كائن من النوع <code>Regexp</code>، والذي يمثل اتحاد الأنماط المعطاة، أي أنه سيتطابق مع أي من أجزائه. يمكن أن تكون الأنماط كائنات من النوع <code>[[Ruby/Regexp|Regexp]]</code>، وفي هذه الحالة سيتم الاحتفاظ بخياراتها، أو يمكن أن تكون سلاسل نصية. إذا لم يتم إعطاء أية أنماط، فسيعيد  القيمة <code>/(?!)/</code>. السلوك سيكون غير محدد إذا احتوى أيُّ من الأنماط المعطاة على التقاط (capture).
 
يُعيد  كائن من النوع <code>Regexp</code>، والذي يمثل اتحاد الأنماط المعطاة، أي أنه سيتطابق مع أي من أجزائه. يمكن أن تكون الأنماط كائنات من النوع <code>[[Ruby/Regexp|Regexp]]</code>، وفي هذه الحالة سيتم الاحتفاظ بخياراتها، أو يمكن أن تكون سلاسل نصية. إذا لم يتم إعطاء أية أنماط، فسيعيد  القيمة <code>/(?!)/</code>. السلوك سيكون غير محدد إذا احتوى أيُّ من الأنماط المعطاة على التقاط (capture).
===[[Ruby/Regexp/equality_operator | التابع ==]]===
+
===[[Ruby/Regexp/equality operator| التابع ==]]===
 
معامل التساوي - يتساوى تعبيران نمطيان إن كان نماطهما متطابقين، وكان لهما نفس رمز مجموعة الحروف (character set code)، وكانت لهمنا نفس قيمة <code>[[Ruby/Regexp/casefold-3F|casefold?‎]]</code>.
 
معامل التساوي - يتساوى تعبيران نمطيان إن كان نماطهما متطابقين، وكان لهما نفس رمز مجموعة الحروف (character set code)، وكانت لهمنا نفس قيمة <code>[[Ruby/Regexp/casefold-3F|casefold?‎]]</code>.
===[[Ruby/Regexp/case_equality | التابع ===]]===
+
===[[Ruby/Regexp/case equality| التابع ===]]===
 
معامل تساوي الحالة (Case Equality) - يُستخدم في العبارات case.
 
معامل تساوي الحالة (Case Equality) - يُستخدم في العبارات case.
===[[Ruby/Regexp/3D~ | التابع =~]]===
+
===[[Ruby/Regexp/3D~| التابع =~]]===
 
يبحث  عن تطابق للتعبير النمطي rxp  ضمن str.
 
يبحث  عن تطابق للتعبير النمطي rxp  ضمن str.
===[[Ruby/Regexp/casefold-3F | التابع casefold?‎]]===
+
===[[Ruby/Regexp/casefold-3F| التابع casefold?‎]]===
 
يعيد  قيمة راية الحساسية لحالة الأحرف (case-insensitive flag).
 
يعيد  قيمة راية الحساسية لحالة الأحرف (case-insensitive flag).
===[[Ruby/Regexp/encoding | التابع encoding]]===
+
===[[Ruby/Regexp/encoding| التابع encoding]]===
 
يُعيد  كائنًا من النوع <code>[[Ruby/Encoding|Encoding]]</code>، والذي يمثل ترميز الكائن .
 
يُعيد  كائنًا من النوع <code>[[Ruby/Encoding|Encoding]]</code>، والذي يمثل ترميز الكائن .
===[[Ruby/Regexp/eql-3F | التابع eql?‎]]===
+
===[[Ruby/Regexp/eql-3F| التابع eql?‎]]===
 
يعيد  القيمة true إن التعبير النمطي المعطى مساويًا للتعبير النمطي ، أي إن كان نمطاهما متطابقان، وكان لهما نفس رمز مجموعة الحروف (haracter set code)، وكانت لهما نفس قيمة <code>[[Ruby/Regexp/casefold-3F|casefold?‎]]</code>.
 
يعيد  القيمة true إن التعبير النمطي المعطى مساويًا للتعبير النمطي ، أي إن كان نمطاهما متطابقان، وكان لهما نفس رمز مجموعة الحروف (haracter set code)، وكانت لهما نفس قيمة <code>[[Ruby/Regexp/casefold-3F|casefold?‎]]</code>.
===[[Ruby/Regexp/fixed_encoding-3F | التابع fixed_encoding?‎]]===
+
===[[Ruby/Regexp/fixed encoding-3F| التابع fixed_encoding?‎]]===
 
يُعيد  القيمة false إن كان التعبير النمطي  قابلًا للتطبيق على سلسلة نصية ذات ترميز متوافق مع ASCII. أو يعيد true خلاف ذلك.
 
يُعيد  القيمة false إن كان التعبير النمطي  قابلًا للتطبيق على سلسلة نصية ذات ترميز متوافق مع ASCII. أو يعيد true خلاف ذلك.
===[[Ruby/Regexp/hash | التابع hash]]===
+
===[[Ruby/Regexp/hash| التابع hash]]===
 
يعيد  رمز تكويد (hash) استنادًا إلى نص وخيارات هذا التعبير النمطي.
 
يعيد  رمز تكويد (hash) استنادًا إلى نص وخيارات هذا التعبير النمطي.
===[[Ruby/Regexp/inspect | التابع inspect]]===
+
===[[Ruby/Regexp/inspect| التابع inspect]]===
 
يعيد  نسخة نصية منسقة من التعبير النمطي . قد يكون من المفاجئ أن تعلم أن <code>#inspect</code> ينتج في الواقع نسخة طبيعية من السلسلة النصية أكثر حتى من التابع <code>#to_s</code>.
 
يعيد  نسخة نصية منسقة من التعبير النمطي . قد يكون من المفاجئ أن تعلم أن <code>#inspect</code> ينتج في الواقع نسخة طبيعية من السلسلة النصية أكثر حتى من التابع <code>#to_s</code>.
===[[Ruby/Regexp/match | التابع match]]===
+
===[[Ruby/Regexp/match| التابع match]]===
 
يُعيد  كائنًا من النوع <code>MatchData</code> يصف المطابقة، أو يعيد <code>nil</code> إذا لم يكن هناك تطابق. هذا يُكافئ استرداد قيمة المتغير الخاص <code>$~</code> بعد مطابقة عادية. في حال تمرير الوسيط الثاني،، فإنه يحدد الموضع في السلسلة النصية لبدء البحث.
 
يُعيد  كائنًا من النوع <code>MatchData</code> يصف المطابقة، أو يعيد <code>nil</code> إذا لم يكن هناك تطابق. هذا يُكافئ استرداد قيمة المتغير الخاص <code>$~</code> بعد مطابقة عادية. في حال تمرير الوسيط الثاني،، فإنه يحدد الموضع في السلسلة النصية لبدء البحث.
===[[Ruby/Regexp/match-3F | التابع match?‎]]===
+
===[[Ruby/Regexp/match-3F| التابع match?‎]]===
 
يُعيد  القيمة <code>true</code> أو <code>false</code> بحسب ما إذا كان التعبير النمطي قد طوبِق أم لا دون تحديث المتغير $~ والمتغيرات الأخرى ذات الصلة. في حال إعطاء الوسيط الثاني، فإنّه يحدد الموضع في السلسلة النصية لبدء البحث.
 
يُعيد  القيمة <code>true</code> أو <code>false</code> بحسب ما إذا كان التعبير النمطي قد طوبِق أم لا دون تحديث المتغير $~ والمتغيرات الأخرى ذات الصلة. في حال إعطاء الوسيط الثاني، فإنّه يحدد الموضع في السلسلة النصية لبدء البحث.
===[[Ruby/Regexp/named_captures | التابع named_captures]]===
+
===[[Ruby/Regexp/named captures| التابع named_captures]]===
 
يُعيد  قاموسًا (hash) يحتوي معلومات حول الالتقاطات المسماة (named captures) لتتعبير النمطي .
 
يُعيد  قاموسًا (hash) يحتوي معلومات حول الالتقاطات المسماة (named captures) لتتعبير النمطي .
===[[Ruby/Regexp/names | التابع names]]===
+
===[[Ruby/Regexp/names| التابع names]]===
 
يعيد  قائمة بأسماء الأجزاء المُلتقطة (captures) على هبئة مصفوفة من سلاسل نصية.
 
يعيد  قائمة بأسماء الأجزاء المُلتقطة (captures) على هبئة مصفوفة من سلاسل نصية.
===[[Ruby/Regexp/options | التابع options]]===
+
===[[Ruby/Regexp/options| التابع options]]===
 
يُعيد مجموعة البتات (bits) المقابلة للخيارات المستخدمة عند إنشاء الكائن <code>[[Ruby/Regexp|Regexp]]</code> (انظر صفحة <code>Regexp::new</code> لمزيد من التفاصيل. لاحظ أنه قد يتم وضع بتات إضافية في الخيارات المُعادة: والتي تُستخدم داخليًا بواسطة في التعبير النمطي. يتم تجاهل هذه البتات الإضافية إذا تم تمرير الخيارات إلى <code>Regexp::new</code>.
 
يُعيد مجموعة البتات (bits) المقابلة للخيارات المستخدمة عند إنشاء الكائن <code>[[Ruby/Regexp|Regexp]]</code> (انظر صفحة <code>Regexp::new</code> لمزيد من التفاصيل. لاحظ أنه قد يتم وضع بتات إضافية في الخيارات المُعادة: والتي تُستخدم داخليًا بواسطة في التعبير النمطي. يتم تجاهل هذه البتات الإضافية إذا تم تمرير الخيارات إلى <code>Regexp::new</code>.
===[[Ruby/Regexp/source | التابع source]]===
+
===[[Ruby/Regexp/source| التابع source]]===
 
يعيد  السلسلة النصية الأصلية للنمط.
 
يعيد  السلسلة النصية الأصلية للنمط.
===[[Ruby/Regexp/to_s | التابع to_s]]===
+
===[[Ruby/Regexp/to s| التابع to_s]]===
 
يُعيد  سلسلة نصية تحتوي على التعبير النمطي وخياراته (باستخدام الصياغة <code>(?opts:source)</code>). يمكن إعطاء هذه السلسلة النصية مرة أخرى إلى المُنشئ <code>Regexp::new</code> لإنشاء تعبير نمطي مشابه للتعبير النمطي الأصلي. (لكن مع ذلك، قد لا يعيد المعامل <code>Regexp#==</code> القيمة trueعند مقارنتهما، حيث قد يختلف مصدر التعبير النمطي نفسه، كما يظهر المثال).  ينتج التابع <code>Regexp#inspect</code> نسخة ذات مقروئية أفضل بشكل عام للتعبير النمطي.
 
يُعيد  سلسلة نصية تحتوي على التعبير النمطي وخياراته (باستخدام الصياغة <code>(?opts:source)</code>). يمكن إعطاء هذه السلسلة النصية مرة أخرى إلى المُنشئ <code>Regexp::new</code> لإنشاء تعبير نمطي مشابه للتعبير النمطي الأصلي. (لكن مع ذلك، قد لا يعيد المعامل <code>Regexp#==</code> القيمة trueعند مقارنتهما، حيث قد يختلف مصدر التعبير النمطي نفسه، كما يظهر المثال).  ينتج التابع <code>Regexp#inspect</code> نسخة ذات مقروئية أفضل بشكل عام للتعبير النمطي.
===[[Ruby/Regexp/~ | التابع ~]]===
+
===[[Ruby/Regexp/~| التابع ~]]===
 
يبحث  عن مطابقة التعبير النمطي  في محتويات المتغير <code>$_</code>. وهو مُكافئ للتعبير <code>rxp  =~ $_</code>.
 
يبحث  عن مطابقة التعبير النمطي  في محتويات المتغير <code>$_</code>. وهو مُكافئ للتعبير <code>rxp  =~ $_</code>.
 +
 
*[http://ruby-doc.org/core-2.5.1/Regexp.html قسم  الصنف Regexp في توثيق روبي الرسمي.]
 
*[http://ruby-doc.org/core-2.5.1/Regexp.html قسم  الصنف Regexp في توثيق روبي الرسمي.]

مراجعة 15:02، 1 نوفمبر 2018

كائنات الصنف Regexp التعابير النمطية، والتي تُستخدم لمطابقة نمط (pattern) معيّن في سلسلة نصية. يتم إنشاء التعابير النمطية باستخدام الصياغتين /.../ و ‎%r{...}‎، أو بالمنشئ new.

التعابير النمطية هي أنماط تصف محتويات السلسلة النصية. يمكن استخدامها للتحقق من أنّ سلسلة نصية تحتوي على نمط معين، أو لاستخراج الأجزاء المُطابقة. يتم إنشاؤها باستخدام الصياغتين /pat/ و ‎%r{pat}‎، أو باستخدام المنشئ new.

عادة ما يتم تحديد التعبير النمطي بعارضة مائلة للأمام (/). كمل يوضح المثال أدناه:

/hay/ =~ 'haystack'   #=> 0
/y/.match('haystack') #=> #<MatchData "y">

إذا احتوت سلسلة نصية على النمط فسيقال أنها مُطابقة، أو تتطابق مع التعبير النمطي. كل سلسلة نصية حرفية (literal) تطابق نفسها. في المثال الموالي، السلسلة النصية 'haystack' لا تحتوي على النمط 'needle'، لذلك فهي لا تتطابق:

/needle/.match('haystack') #=> nil

أماا في هذا المثال، فالسلسلة النصية 'haystack' تحتوي على النمط 'hay'، لذلك فهي تتطابق:

/hay/.match('haystack')    #=> #<MatchData "hay">

بشكل أكثر تحديدًا، يتطلب التعبير النمطي /st/ أن تحتوي السلسلة النصية على الحرف s متبوعاً بالحرف t ، لذلك فهي تتطابق مع "haystack" أيضًا.

المعامل ‎=~ ‎و التابع match

يمكن التحقق من مطابقة النمط باستخدام المعامل ‎=~‎ أو التابع match.

المعامل ‎=~‎

=~‎ هو معامل المُطابقة الأساسي في روبي. عندما يكون أحد معامليه عبارة عن تعبير نمطي، والآخر عبارة عن سلسلة نصية، فسيُستخدم التعبير النمطي حينها كنمط لمطابقة السلسلة النصية. (تعريف هذا المعامل في الصنفين Regexp و String متماثل، لذا لا يهم ترتيب السلسلة النصية أو التعبيرالنمطي لا يهم. قد يكون للأصناف الأخرى تقديمات (implementations) مختلفة للمعامل ‎=~‎.) في حالة العثور على تطابق، فسيعيد المعامل فهرس المطابقة الأولى في السلسلة النصية، وإلا فسيعيد nil.

/hay/ =~ 'haystack'   #=> 0
'haystack' =~ /hay/   #=> 0
/a/   =~ 'haystack'   #=> 1
/u/   =~ 'haystack'   #=> nil

عند استخدام المعامل ‎=~‎ مع كائن من النوع String أو Regexp، سيتم تعيين المتغير العام ‎$~‎ بعد الحصول على مطابقة ناجحة. سيحتوي المتغير ‎‎‎‎‎$~‎‎‎ على كائن من النوع MatchData.

التابعlast_match مكافئ للمتغير ‎$~‎.

التابع match

يعيد التابع match كائنًا من النوع MatchData:

/st/.match('haystack')   #=> #<MatchData "st">

الحروف الخاصة (Metacharacters) وحروف التخليص (Escapes)

الحروف التالية هي حروف خاصة (metacharacters):

( و ) و [ و ] و { و } و . و ? و + و *. لهذه الحروف معاني محددة عندما تظهر في تعبير نمطي. لمطابقتها حرفياً، يجب أن تكون مسبوقة بعارضة مائلة للخلف \. لمطابقة العارضة المائلة للخلف حرفياً، يجب أن تكون مسبوقة كذلك بعارضة مائلة للخلف: \\

/1 \+ 2 = 3\?/.match('Does 1 + 2 = 3?') #=> #<MatchData "1 + 2 = 3?">
/a\\\\b/.match('a\\\\b')                    #=> #<MatchData "a\\b">

تتصرف الأنماط مثل السلاسل النصية المُقتبسة (double-quoted) بحيث يمكن أن تحتوي على نفس الشرطة المائلة للخلف المخصصة لأجل التخليص (backslash escapes).

/\s\u{6771 4eac 90fd}/.match("Go to 東京都")
    #=> #<MatchData " 東京都">

يمكن تضمين تعابير روبي في الأنماط عبر الصياغة ‎#{...}‎.

place = "東京都"
/#{place}/.match("Go to 東京都")
    #=> #<MatchData "東京都">

مجموعات الحروف (Character Classes)

يتم تحديد مجموعات الحروف (character class) بواسطة الأقواس المربعة ([ ، ]) وتوضع بينها الأحرف التي قد تظهر عند هذه النقطة في المطابقة. التعبير النمطي /[ab]/ يعني إما a أو b، على خلاف /ab/ الذي يعني الحرف a متبوعاً بالحرف b.

/W[aeiou]rd/.match("Word") #=> #<MatchData "Word">

ضمن مجموعات الحروف، تمثل الشرطة (-) حرفًا خاصا يشير إلى مجال شامل (inclusive) مكون من أحرف. التعبير النمطي [abcd] يكافئ [a-d]. يمكن أن يُتبع المجال بمجال آخر، لذلك فالتعبير النمطي [abcdwxyz] يكافئ [a-dw-z]. ولا يهم الترتيب الذي تظهر به المجالات أو الأحرف الفردية داخل مجموعة الحروف.

/[0-9a-f]/.match('9f') #=> #<MatchData "9">
/[9f]/.match('9f')     #=> #<MatchData "9">

إذا كان أول حرف من حروف المجموعة هو العلامة (^)، فستُعكس المجموعة: أي أنها ستطابق أي حرف باستثناء تلك المحددة في المجموعة.

/[^a-eg-z]/.match('f') #=> #<MatchData "f">

يمكن أن تحتوي مجموعة حروف على مجموعة حروف أخرى. الشكل ‎[a-z[0-9]]‎ يصف نفس المجموعة [a-z0-9]. كما أنّ مجموعات الحروف تدعم المعامل && الذي يجري عملية التقاطع على وسائطه. ويمكن دمج الاثنين كما يلي:

/[a-w&&[^c-g]z]/ # ([a-w] AND ([^c-g] OR z))

هذا يُكافئ:

/[abh-w]/

تتصرف الحروف الخاصة (metacharacters) التالية مثل مجموعات الحروف:

  • /./ - أي حرف باستثناء محرف السطر الجديد.
  • /./m - أي حرف (المُعدِّل m يتيح الوضع متعدد الأسطر)
  • /\w/‎ - حرف كلمة ([a-zA-Z0-9_‎])
  • ‎‎‎‎‎/\W/‎ - ُحرف يخالف حروف الكلمة ([‎^a-zA-Z0-9_‎‎]). يرجى إلقاء نظرة على صفحة الخطأ Bug#4044 في حالة استخدام ‎‎‎‎‎/\W/‎ مع المُعدِّل ‎/i‎.
  • /\d/‎ - حرف رقمي ([‎0-9])
  • /\D/‎ - حرف غير رقمي ([‎^0-9])
  • /\h/ ‎- حرف ستة عشري ([‎0-9a-fA-F])
  • /\H/‎ - حرف غير ستة عشري ([‎^0-9a-fA-F])
  • /\s/‎ - حرف من حروف المسافات البيضاء: /[‎ \t\r\n\f\v]/
  • /\S/‎ - حرف يخالف حروف المسافة البيضاء: /[‎^‎ \t\r\n\f\v]/

تعبيرات أقواس POSIX ‏(POSIX bracket expressions) مشابهة لمجموعات الحروف. إذ توفر بديلاً محمولًا (portable) لما سبق، مع ميزة إضافية تتمثل في أنها يمكن أن تحتوي على أحرف من خارج الترميز ASCII. على سبيل المثال، لا يطابق التعبير ‏‏‎/\d/‎‏ إلا الأرقام العشرية للترميز ASCII ‏(0-9)؛ بينما يطابق التعبير /[[:digit:]]/ أي حرف من مجموعة الحروف العددية Nd في اليونيكود (Unicode Nd).

  • /[[:alnum:]]/- حرف أبجدي أو رقم
  • /[[:alpha:]]/ - حرف أبجدي
  • /[[:blank:]]/ - فراغ أو علامة تبويب (tab)
  • /[[:cntrl:]]/ - حرف تحكم (Control character)
  • /[[:digit:]]/ - رقم
  • /[[:graph:]]/ - حرف غير فارغ (يستثني المسافات وأحرف التحكم وما شابه)
  • /[[:lower:]]/ - الأحرف الأبجدية الصغيرة
  • /[[:print:]]/ - مثل [:graph:]، ولكنها تتضمن حرف المسافة
  • /[[:punct:]]/ - علامة ترقيم (Punctuation character)
  • /[[:space:]]/ - محرف مسافة بيضاء ([:blank:] أو سطر جديد أو حرف الرجوع [carriage return]، وما إلى ذلك)
  • /[[:upper:]]/ - حرف أبجدي كبير
  • /[[:xdigit:]]/ - رقم من الأرقام المسموح بها في الأعداد السداسي عشرية (أي الحروف ‎0-9a-fA-F)

تدعم روبي أيضًا مجموعات الحروف التالية بجانب مجموعات POSIX:

  • /[[:word:]]/ - حرف من إحدى مجموعات حروف اليونيكود العامة التالية Letter و Mark و Number و Connector_Punctuation.
  • /[[:ascii:]]/ - حرف من مجموعة حروف ASCII.
# U+06F2 is "EXTENDED ARABIC-INDIC DIGIT TWO"
/[[:digit:]]/.match("\u06F2")    #=> #<MatchData "\u{06F2}">
/[[:upper:]][[:lower:]]/.match("Hello") #=> #<MatchData "He">
/[[:xdigit:]][[:xdigit:]]/.match("A6")  #=> #<MatchData "A6">

التكرار

تتطابق التركيبات الموصوفة حتى الآن مع حرف واحد، لكن ماذا لو أردنا مطابقة أكثر من حرف دفعة واحدة. يمكننا ذلك باستخدام حروف خاصة تُسمى المُكممات (quantifiers). والتي توضع بعد الحرف الذي نريد أن يتكرر لتحديد عدد مرات ظهوره، هذه المكممات هي:

  • * - صفر مرّة أو أكثر.
  • + - مرة واحدة أو أكثر
  • ? - صفر مرة أو مرة واحدة (اختياري)
  • {n} - بالضبط n مرة
  • {n,} - على الأقل أكثر n مرة
  • {,m} - على الأكثر m مرة
  • {n,m} - بين n و m مرة

'مثال': على الأقل حرف كبير واحد ('H')، ثم حرف واحد صغير على الأقل ('e')، ثم حرفين 'l'، ثم حرف 'o':

"Hello".match(/[[:upper:]]+[[:lower:]]+l{2}o/) #=> #<MatchData "Hello">

أنماط التكرار طمّاعة (greedy) افتراضيًا: أي أنها تبحث عن مطابقة أكبر جزء ممكن يحقق المطابقة من السلسلة النصية. على خلاف ذلك، فإن المطابقة القانعة (lazy matching) تكتفي بالحد الأدنى من السلسلة النصية الذي يحقق المطابقة بشكل عام.

يمكن جعل الحروف الخاصة الطماعة قانعة باتباعها بالحرف ?.

كلا النمطين أدناه يتطابقان مع السلسلة النصية. يستخدم الأول مُكمما طماعًا، بحيث يطابق "‎.+‎" السلسة النصية "<a> " ؛ أما الثاني فيستخدم مكمما قانعا،بحيث يطابق '‎.+?‎'السلسلة النصية '<a>':

/<.+>/.match("<a><b>")  #=> #<MatchData "<a><b>">
/<.+?>/.match("<a><b>") #=> #<MatchData "<a>">

المكممات المتبوعة بالعلامة + تُطابق تملكيًا (possessively): فبمجرد أن تُطابق نمطًا فلن تتراجع. فهي تتصرف مثل المكممات الطماعة، ولكنها ترفض "التخلي" عن الأجزاء التي طابقتها حتى لو كان ذلك سيُفشل كامل المطابقة.

الالتقاط (Capturing)

يمكن استخدام الأقواس لأجل الالتقاط (capturing). ويمكن لاحقًا التأشير إلى النص المتضمن في مجموعة الأقواس رقم n بالعدد n. داخل النمط استخدم المؤشر ‎\n، أما خارج النمط فاستخدم MatchData[n]‎.

في المثال أدناه، تلتقط "at" بالزوج الأول من الأقواس، ثم يتم التأشير إليها باستخدام ‎\1:

/[csh](..) [csh]\1 in/.match("The cat sat in the hat")
   #=> #<MatchData "cat sat in" 1:"at">

يعيد التابع match كائنًا من النوع MatchData، والذي يجعل النص الذي تم التقاطه متاحًا عبر معامل الفهرسة []:

/[csh](..) [csh]\1 in/.match("The cat sat in the hat")[1] #=> 'at'

يمكن التأشير إلى المجموعات الملتقطة باسمها الذي عُرّفت به في حال تعريفها وفق الصياغة (?<name>) أو (?'name').

/\$(?<dollars>\d+)\.(?<cents>\d+)/.match("$3.67")
   #=> #<MatchData "$3.67" dollars:"3" cents:"67">
/\$(?<dollars>\d+)\.(?<cents>\d+)/.match("$3.67")[:dollars] #=> "3"

يمكن التأشير إلى المجموعات المُسماة بواسطة ‎\k<name>‎، حيث name هو اسم المجموعة.

/(?<vowel>[aeiou]).\k<vowel>.\k<vowel>/.match('ototomy')
   #=> #<MatchData "ototo" vowel:"o">

ملاحظة: لا يمكن للتعبير النمطي استخدام المؤشرات المسماة (named backreferences) والمؤشرات الرقمية (numbered backreferences) في وقت واحد. عند استخدام مجموعات الالتقاط المسماة (named capture groups) مع تعبير نمطي حرفي على الجانب الأيسر من التعبير والمعامل ‎=~‎، فسيتم تخزين النص الذي تم التقاطه في متغيرات محلية تحمل أسماء مشابهة.

/\$(?<dollars>\d+)\.(?<cents>\d+)/ =~ "$3.67" #=> 0
dollars #=> "3"

التجميع (Grouping)

تُجمّع (group) الأقواس التعابير التي تُطوّقها، مما يسمح بتحديدها كمجموعة واحدة. يتطابق النمط أدناه مع حرف متحرك (vowel) متبوع بحرفي كلمة (word characters):

/[aeiou]\w{2}/.match("Caenorhabditis elegans") #=> #<MatchData "aen">

بينما يتطابق النمط التالي مع حرف متحرك يتبعه حرف كلمة، مرتين ، أي‎[aeiou]\w[aeiou]\w: ‏"enor".

/([aeiou]\w){2}/.match("Caenorhabditis elegans")
   #=> #<MatchData "enor" 1:"or">

يتيح التعبير (‎?:…‎) إمكانية التجميع، لكن بدون التقاط. هذا يعني أنه يُجمّع التعابير التي يحتوي عليها في وحدة غير قابلة للتجزيئ (atom) دون إنشاء مؤشر إليها (backreference). هذا يفيد في تحسين الأداء، لكن على حساب إضرار طفيف بقابلية القراءة. في المثال أدناه، الزوج الأول من الأقواس يلتقط "n"، أما الثاني فيلتقط "ti". تتم الإشارة إلى المجموعة الثانية لاحقًا باستخدام المؤشر ‎\2:

/I(n)ves(ti)ga\2ons/.match("Investigations")
   #=> #<MatchData "Investigations" 1:"n" 2:"ti">

لقط أصبح الزوج الأول من الأقواس غير قابل للالتقاط بسبب استخدام ‎?:‎، لذلك قسيتطابق مع "n"، ولكنه لن ينشئ مؤشرًا إليه. وبالتالي ، فالمؤشر ‎\1 يشير الآن إلى "ti".

/I(?:n)ves(ti)ga\1ons/.match("Investigations")
   #=> #<MatchData "Investigations" 1:"ti">

التجميع الذري (Atomic Grouping)

يمكن جعل التجميعات ذرية بواسطة التعبير (‎?>pat). هذا سيؤدي إلى مطابقة التعبير الجزئي (subexpression) بشكل مستقل عن بقية التعبير، بحيث أنّ ما يطابقه سيصبح ثابتًا لبقية المطابقة، ما لم يتم التخلي عن التعبير الجزئي بأكمله وإعادة النظر فيه لاحقًا. بهذه الطريقة، تعامل pat باعتبارها وحدة غير قابلة للتجزيئ (ذرة).

يتم استخدام التجميع الذري عادة لتحسين أداء الأنماط، وكذلك لمنع إنشاء مؤشرات (backtracking) بدون داعٍ.

يتطابق " في النمط أدناه مع الحرف الأول من السلسلة النصية، ثم يُطابق ‎.*‎ علامة التنصيص ". يؤدي هذا إلى فشل المطابقة الإجمالية، وهكذا فالنص المطابق لـ ‎.*‎ يُؤشّر إليه (backtracked) بموضع واحد، مما يجعل الحرف النهائي للسلسلة النصية متاحًا لمطابقة "

/".*"/.match('"Quote"')     #=> #<MatchData "\"Quote\"">

إذا تم تجميع ‎.*‎ ذريًا، فسيرفض إنشاء مرجع للعلامة "، على الرغم من أنّ هذا سيعني أن المطابقة الإجمالية ستفشل

/"(?>.*)"/.match('"Quote"') #=> nil

استدعاء التعابير الجزئية (Subexpression Calls)

تطابق الصياغة ‎\g<name>‎ التعبير الجزئي السابق المسمى name، والذي يمكن أن يكون اسم مجموعة أو رقم. هذا مُختلف عن التأشير في كونه يعيد معالجة المجموعة بدلاً من مجرد محاولة إعادة مطابقة نفس النص.

يتطابق النمط التالي مع الحرف (ويُحيله إلى المجموعة paren، ويحاول استدعاء التعبير الجزئي للمجموعة paren مرة أخرى، لكنه يفشل، ثم يطابق الحرف ):

/\A(?<paren>\(\g<paren>*\))*\z/ =~ '()'
/\A(?<paren>\(\g<paren>*\))*\z/ =~ '(())' #=> 0
# ^1
#      ^2
#           ^3
#                 ^4
#      ^5
#           ^6
#                      ^7
#                       ^8
#                       ^9
#                           ^10
  1. يطابق بداية السلسلة النصية، أي قبل الحرف الأول.
  2. يدخل مجموعة التقاط مسماة (named capture group) تحمل الاسمparen
  3. يطابق المحرف (، الحرف الأول في السلسلة النصية
  4. يستدعي المجموعة paren مرة أخرى، أي يعاود الرجوع (recurses) مرة أخرى إلى الخطوة الثانية
  5. يعيد الدخول إلى المجموعة paren
  6. يطابق المحرف (، الحرف الثاني في السلسلة النصية
  7. يحاول استدعاء paren للمرة الثالثة، ولكن يفشله، لأن ذلك من شأنه أن يمنع مطابقة ناجحة شاملة
  8. يطابق المحرف )، أي الحرف الثالث في السلسلة النصية.
  9. يحدد نهاية الاستدعاء العودي (recursive) الثاني
  10. يطابق المحرف )، الحرف الرابع في السلسلة النصية
  11. يطابق نهاية السلسلة النصية

البدائل (Alternation)

يُؤلّف الحرف الخاص (|) بين تعبيرين في تعبير واحد يطابق أيًا من ذَيْنِكَ التعبيرين. فكل تعبير هو بديل ممكن.

/\w(and|or)\w/.match("Feliformia") #=> #<MatchData "form" 1:"or">
/\w(and|or)\w/.match("furandi")    #=> #<MatchData "randi" 1:"and">
/\w(and|or)\w/.match("dissemblance") #=> nil

خاصيات الحروف (Character Properties)

تُطابق الصياغة ‎\p{}‎ الحروف ذات الخاصية المعطاة، وهي مشابهة لمجموعات أقواس POSIX.

  • /p{Alnum}‎\/ - حرف أبجدي أو رقمي
  • /p{Alpha}‎\/ - حرف أبجدي
  • /p{Blank}‎\/ - مسافة بيضاء أو علامة تبويب (tab)
  • /p{Cntrl}‎\/ - محرف تحكم (Control character)
  • /p{Digit}‎\/ - رقم
  • /p{Graph}‎\/ - حرف غير فارغ (يستثني المسافات البيضاء وأحرف التحكم وما شابه)
  • /p{Lower}‎\/ - حرف أبجدي صغير
  • /p{Print}\/ - مثل ‎\p{Graph}‎ ، ولكنه يتضمن المسافة البيضاء
  • /p{Punct}‎/ - علامة ترقيم
  • /p{Space}‎\/ - حرف مسافة بيضاء ([:blank:] أو سطر جديد أو حرف إرجاع [carriage return]، إلخ)
  • /p{Upper}‎\/ - حرف أبجدي كبير
  • /p‎‎{XDigit}‎\/ - رقم من الأرقام المسموح بها في الأعداد السداسي عشرية (على سبيل المثال ، 0-9a-fA-F)
  • /p{Word}‎\/ - عنصر من إحدى مجموعات اليونيكود العامة التالية Letter، Mark، Number، Connector_Punctuation
  • /p{ASCII}‎\/ - حرف من حروف ASCII.
  • /p{Any}‎\/ - أي حرف من حروف اليونيكود (بما في ذلك الأحرف غير المعينة [unassigned]).
  • /p{Assigned}‎\/ - حرف معين (assigned character).

يمكن أيضًا مطابقة حرف من مجموعة اليونيكود General Category بالنمط ‎\p{Ab}‎ حيث Ab يمثل اختصار المجموعة كما هو موضح أدناه:

/\p{L}/ - 'Letter'

/\p{Ll}/ - 'Letter: Lowercase'

/\p{Lm}/ - 'Letter: Mark'

/\p{Lo}/ - 'Letter: Other'

/\p{Lt}/ - 'Letter: Titlecase'

/\p{Lu}/ - 'Letter: Uppercase

/\p{Lo}/ - 'Letter: Other'

/\p{M}/ - 'Mark'

/\p{Mn}/ - 'Mark: Nonspacing'

/\p{Mc}/ - 'Mark: Spacing Combining'

/\p{Me}/ - 'Mark: Enclosing'

/\p{N}/ - 'Number'

/\p{Nd}/ - 'Number: Decimal Digit'

/\p{Nl}/ - 'Number: Letter'

/\p{No}/ - 'Number: Other'

/\p{P}/ - 'Punctuation'

/\p{Pc}/ - 'Punctuation: Connector'

/\p{Pd}/ - 'Punctuation: Dash'

/\p{Ps}/ - 'Punctuation: Open'

/\p{Pe}/ - 'Punctuation: Close'

/\p{Pi}/ - 'Punctuation: Initial Quote'

/\p{Pf}/ - 'Punctuation: Final Quote'

/\p{Po}/ - 'Punctuation: Other'

/\p{S}/ - 'Symbol'

/\p{Sm}/ - 'Symbol: Math'

/\p{Sc}/ - 'Symbol: Currency'

/\p{Sc}/ - 'Symbol: Currency'

/\p{Sk}/ - 'Symbol: Modifier'

/\p{So}/ - 'Symbol: Other'

/\p{Z}/ - 'Separator'

/\p{Zs}/ - 'Separator: Space'

/\p{Zl}/ - 'Separator: Line'

/\p{Zp}/ - 'Separator: Paragraph'

/\p{C}/ - 'Other'

/\p{Cc}/ - 'Other: Control'

/\p{Cf}/ - 'Other: Format'

/\p{Cn}/ - 'Other: Not Assigned'

/\p{Co}/ - 'Other: Private Use'

/\p{Cs}/ - 'Other: Surrogate'

في الأخير، تطابق ‎\p{}‎ محارف خطوط اليونيكود، الخطوط التالية مدعومة:

Arabic, Armenian, Balinese, Bengali, Bopomofo, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, Cham, Cherokee, Common, Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, Devanagari, Ethiopic, Georgian, Glagolitic, Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hiragana, Inherited, Kannada, Katakana, Kayah_Li, Kharoshthi, Khmer, Lao, Latin, Lepcha, Limbu, Linear_B, Lycian, Lydian, Malayalam, Mongolian, Myanmar, New_Tai_Lue, Nko, Ogham, Ol_Chiki, Old_Italic, Old_Persian, Oriya, Osmanya, Phags_Pa, Phoenician, Rejang, Runic, Saurashtra, Shavian, Sinhala, Sundanese, Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, Ugaritic, Vai, and Yi

محرف اليونيكود U+06E9 يُسمى "ARABIC PLACE of SAJDAH" (موضع سجدة)، وينتمي إلى الخط العربي:

/\p{Arabic}/.match("\u06E9") #=> #<MatchData "\u06E9">

يمكن عكس جميع خصائص الأحرف عن طريق إضافة البادئة (^) إلى أسمائها. الحرف "A" ليس مُتضمّنًا في مجموعة اليونيكود Ll [التي تعني (Letter; Lowercase)]، لذلك تنجح المطابقة التالية:

/\p{^Ll}/.match("A") #=> #<MatchData "A">

المراسي (Anchors)

المراسي (Anchors) هي حروف خاصة تُطابق مواضع معدومة الطول بين الأحرف، وتربط المطابقة بموضع معين.

  • ^ - تطابق بداية السطر
  • $ - تطابق نهاية السطر
  • \A - تطابق بداية السلسلة النصية.
  • \Z - تطابق نهاية السلسلة النصية. إذا انتهت السلسلة النصية بسطر جديد، فستُطابق الموضع الموجود قبل السطر الجديد مباشرة
  • \z - تطابق نهاية السلسلة النصية
  • \G - تطابق أول موضع مطابقة: في توابع مثل String#gsub و String#scan، تتغير عند كل تكرار. حيث تتطابق في البداية مع بداية الموضوع، وفي كل تكرار تطابق مكان انتهاء المطابقة الأخيرة
"    a b c".gsub(/ /, '_')    #=> "____a_b_c"
"    a b c".gsub(/\G /, '_')  #=> "____a b c"

في التوابع التي تأخذ موضعًا (اختياريًا)، مثل Regexp#match و String#match، ستُطابق مكان بدء البحث.

"hello, world".match(/,/, 3)    #=> #<MatchData ",">
"hello, world".match(/\G,/, 3)  #=> nil
  • \b - تطابق مواضع حدود الكلمات (word boundaries) عندما تكون خارج الأقواس؛ وتطابق محرف التراجع backspace‏ (0x08) عندما تكون داخل الأقواس
  • \B - تُطابق المواضع المخالفة لحدود الكلمات
  • (‎?=pat) - المطالعة الأمامية الإيجابية (Positive lookahead assertion): تتأكد من أنّ الأحرف التالية تتطابق مع pat، ولكن لا تتضمن تلك الأحرف في النص المُطابق
  • (‎?!pat) - المطالعة الأمامية السلبية (Negative lookahead assertion): تتأكد من أنّ الأحرف التالية لا تتطابق مع pat، ولكن لا تتضمن تلك الأحرف في النص المُطابق
  • (‎?<=pat) -المطالعة الخلفية الإيجابية (Positive lookbehind assertion): تتأكد من تطابق الأحرف السابقة مع pat، ولكنها لا تتضمّن تلك الأحرف في النص المُطابق
  • (‎?<!pat) - المطالعة الخلفية الإيجابية (Negative lookbehind assertion): تتأكد من أنّ الأحرف السابقة لا تتطابق مع pat، ولكنها لا تتضمن تلك الأحرف في النص المُطابق

إذا لم يتم وضع مرساة (anchor) للنمط، فيمكنه أن يبدأ من أي نقطة في السلسلة النصية:

/real/.match("surrealist") #=> #<MatchData "real">

إرساء (Anchoring) النمط عند بداية السلسلة النصية يفرض بدء المطابقة هناك. في المثال الآتي، لا تظهر "real" في بداية السلسلة النصية، لذلك تفشل المطابقة:

/\Areal/.match("surrealist") #=> nil

تفشل المطابقة أدناه لأنه على الرغم من أن "Demand" تحتوي "and" ، فإنّ النمط لا يظهر عند حدود الكلمات (word boundary).

/\band/.match("Demand")

في حين أنّه في المثال التالي السلسلة النصية "and" تم إرساؤها عند المواضع المخالفة لحدود الكلمات (non-word boundary)، لذلك، فبدلاً من مطابقة "and" الأولى، فستتطابق مع الحرف الرابع من "demand" بدلاً من ذلك:

/\Band.+/.match("Supply and demand curve") #=> #<MatchData "and curve">

يستخدم النمط التالي المطالعة الأمامية الإيجابية و االمطالعة الخلفية الإيجابية لمطابقة النص الوارد في الوسوم (tags) دون تضمين الوسوم في المطابقة:

/(?<=<b>)\w+(?=<\/b>)/.match("Fortune favours the <b>bold</b>")
   #=> #<MatchData "bold">

الخيارات

يمكن أن يُعقب محدد النهاية للتعبير النمطي بحرف واحد أو أكثر يمثل الخيارات التي تتحكم في كيفية مطابقة النمط.

  • /pat/i - يتجاهل حالة الأحرف
  • /pat/m - تجعل . تطابق محرف السطر الجديد
  • /pat/x - تتجاهل المسافات البيضاء والتعليقات الموجودة في النمط
  • /pat/o - تنفّذ عملية التلقيم‎#{}‎ مرة واحدة فقط

يمكن أيضًا تطبيق الخيارات i وm و x على مستوى التعابير الجزئية (subexpression) عبر الصياغة (‎?on-off)، والتي تفعّل الخيارات on، وتعطّل الخيارات off في التعبير المحاط بالأقواس.

/a(?i:b)c/.match('aBc') #=> #<MatchData "aBc">
/a(?i:b)c/.match('abc') #=> #<MatchData "abc">

كما يمكن استخدام الخيارات مع التابع new:

Regexp.new("abc", Regexp::IGNORECASE)                     #=> /abc/i
Regexp.new("abc", Regexp::MULTILINE)                      #=> /abc/m
Regexp.new("abc # Comment", Regexp::EXTENDED)             #=> /abc # Comment/x
Regexp.new("abc", Regexp::IGNORECASE | Regexp::MULTILINE) #=> /abc/mi

وضع التراص (Free-Spacing Mode) والتعليقات

كما ذُكر أعلاه، يتيح الخيار x وضع التراص (free-spacing mode). حيث يتم تجاهل محارف المسافاة البيضاء (Literal white space) داخل النمط، ويقدم محرف الشباك octothorpe (#) تعليقًا يستمر إلى نهاية السطر. يسمح هذا بتنظيم مكونات النمط بطريقة تجعله أكثر مقروئية.

في المثال التالي يطابق النمط عددًا ذا منازل عشرية اختيارية:

float_pat = /\A
   [[:digit:]]+ # 1 or more digits before the decimal point
   (\.          # Decimal point
       [[:digit:]]+ # 1 or more digits after the decimal point
   )? # The decimal point and following digits are optional
\Z/x
float_pat.match('3.14') #=> #<MatchData "3.14" 1:".14">

هناك عدة استراتيجيات لمطابقة المسافات البيضاء:

  • استخدام أنماط مثل ‎\s أو ‎\p{Space‎}‎.
  • استخدام مسافات بيضاء مُخلّصة (escaped whitespace) مثل " \"، أي مسافة مسبوقة بخط مائل عكسي.
  • استخدام مجموعة حروف مثل [ ].

يمكن تضمين التعليقات في نمط لا يعتمد الخيار ‏x‏ (non-x pattern) باستخدام الصياغة (‎?#comment)، حيث يكون التعليق عبارة عن نص اعتباطي يتم تجاهله من محرك التعبير النمطي.

لا يمكن أن تتضمن التعليقات المُتضمّنة في تعبير نمطي حرفي محرف إنهاء غير مُخلص (unescaped terminator characters).

الترميز Encoding

يفترض أن تستخدم التعابير النمطية ترميز المصدر. يمكن تعديل هذا السلوط بأحد المُعدِّلات التالية.

  • /pat/u يعني UTF-8
  • /pat/e يعني EUC-JP
  • /pat/s يعني Windows-31J
  • /pat/n  يعني ASCII-8BIT

يمكن مطابقة تعبير نمطي مع سلسلة نصية عندما يتشاركان في الترميز، أو إن كان ترميز التعبير النمطي هو US-ASCII، وترميز السلسلة النصية متوافق مع ASCII.

في حال محاولة المطابقة بين ترميزات غير متوافقة، فسيُطلق الاستثناء Encoding::CompatibilityError.

تتحقق الدالة المنطقية fixed_encoding? مما إذا كان للتعبير النمطي ترميز ثابت، ومتوافق مع الترميز ASCII.

يمكن تثبيت ترميز التعبير النمطي بشكل صريح عبر تمرير الثابتة Regexp::FIXEDENCODING كوسيط ثانٍ للتابع Regexp.new:

r = Regexp.new("a".force_encoding("iso-8859-1"),Regexp::FIXEDENCODING)
r =~ "a\u3042"
  # raises Encoding::CompatibilityError: incompatible encoding regexp match
  #         (ISO-8859-1 regexp with UTF-8 string)

متغيرات عامة مخصوصة (Special global variables)

من المهم معرفة بعض المتغيرات العامة:

  • $~‎؛ تكافئ last_match
  • $&‎ تحتوي كامل النص المتطابق؛
  • $`‎تحتوي السلسلة النصية التي تسبق التطابق
  • $'‎ تحتوي السلسلة النصية التي تعقب التطابق؛
  • $1‎‎ و ‎$2 ...، تحتوي النص المُتطابق مع مجموعة الالتقاط الأولى، والثانية، ...؛
  • $+‎ تحتوي آخر مجموعة مُلتقطة.

مثال:

m = /s(\w{2}).*(c)/.match('haystack') #=> #<MatchData "stac" 1:"ta" 2:"c">
$~                                    #=> #<MatchData "stac" 1:"ta" 2:"c">
Regexp.last_match                     #=> #<MatchData "stac" 1:"ta" 2:"c">
$&      #=> "stac"
       # same as m[0]
$`      #=> "hay"
       # same as m.pre_match
$'      #=> "k"
       # same as m.post_match
$1      #=> "ta"
       # same as m[1]
$2      #=> "c"
       # same as m[2]
$3      #=> nil
       # no third group in pattern
$+      #=> "c"
       # same as m[-1]

هذه المتغيرات العامة هي متغيرات مخصوصة بالمهام الفرعية (thread-local)، ومخصوصة بالتوابع (method-local).

الأداء (Performance)

يمكن أن تؤدي بعض التوليفات غير السليمة في الصياغة إلى أداء سيئ جدا.

انظر المثال التالي:

s = 'a' * 25 + 'd' + 'a' * 4 + 'c'
#=> "aaaaaaaaaaaaaaaaaaaaaaaaadaaaac"

تتم مطابقة الأنماط التالية على الفور كما هو متوقع:

/(b|a)/ =~ s #=> 0
/(b|a+)/ =~ s #=> 0
/(b|a+)*/ =~ s #=> 0

أما النمط التالي فيستغرق وقتًا أطول بشكل ملحوظ:

/(b|a+)*c/ =~ s #=> 26

يحدث هذا لأن ذرة (وحدة غير قابلة للتجزئي) في التعبير النمطي مٌكمّمة (quantified) بواسطة كل من الحرف + والحرف *بدون تحديد لمن منهما سيكون التحكم لرحف معين. عدم الوضوح ينتج عنه ينتج أداء خطي فائق (super-linear performance). (راجع Mastering Regular Expressions (3rd ed.)، pp 222 ، بواسطة Jeffery Friedl ، لإجراء تحليل متعمق). يمكن إصلاح هذه المشكلة عن طريق استخدام التجميع الذري، والذي يمنع التأشير غير الضروري: يوضح المثال التالي حالة مشابهة، والتي استغرقت حوالي 60 ثانية للتنفيذ عندي: مطابقة سلسلة نصية مكونة 29 حرف "a" مقابل نمط مؤلف من 29 حرف "a" اختياري يليه 29 إلزاميًا على النحو التالي:

(start = Time.now) && /(b|a+)*c/ =~ s && (Time.now - start)
  #=> 24.702736882
(start = Time.now) && /(?>b|a+)*c/ =~ s && (Time.now - start)
  #=> 0.000166571

حروف "a" التسعة وعشرون الاختيارية تطابق السلسلة النصية، لكن هذا يمنع الحروف التسعة وعشروت الإلزامية الموالية من المطابقة. تتراجع روبي مرارًا وتكرارًا حتى تستوفي أكبر عدد ممكن من التطابقات الاختيارية دون التفريط في المطابقة التسعة وعشرين الإجبارية. من الواضح لنا أنه لا يمكن لأي من المطابقات الاختيارية أن تنجح، ولكن هذه الحقيقة ليست واضحة للأسف لروبي. أفضل طريقة لتحسين الأداء هي تقليل مقدار التراجع المطلوب إلى أقصى حد. في هذه الحالة، بدلاً من المطابقة الفردية لـ 29 حرفًا اختياريًا، يمكن مطابقة مجال اختياريً دفعة واحدة عبر {0،29}:

Regexp.new('a?' * 29 + 'a' * 29) =~ 'a' * 29

توابع الصنف العامة (Public Class Methods)

التابع compile

اسم آخر للتابع Regexp.new

التابع escape

يُخلّص (Escapes) أي حرف يمكن أن يكون له معنى خاص في التعبير النمطي. ثم يعيد سلسلة نصية جديدة مُخلّصة، أو يعيد الكائن (self) في حال عدم تخليص أي أحرف. لكل سلسلة نصية str، ستكون قيمة Regexp.new(Regexp.escape( str ))=~ str مساوية للقيمة true.

التابع last_match

يُعيد في الشكل الأول كائن MatchData الذي تم إنشاؤه من آخر تطابق ناجح للنمط. وهو مكافئ لقراءة المتغير العام المخصوص $~ (راجع المتغيرات العامة المخصوصة في صفحة Regexp لمزيد من التفاصيل).

التابع new

ينشئ تعبيرًا نمطيًا جديدًا من pattern، والذي يمكن أن يكون إما سلسلة نصية (String) أو كائنًا من النوع Regexp (وفي هذه الحالة يتم نشر خيارات التعبير النمطي)، وقد لا يتم تحديد خيارات جديدة (منذ روبي 1.8).

التابع quote

يُخلّص (escapes) أي حرف قد يكون له معنى خاص في التعبير النمطي. ثم يُعيد سلسلة نصية جديدة مُخلّصة، أو يعيد الكائن (self) إذا لم يتم تخليص أي أحرف. لكل سلسلة نصية str، ستكون قيمة التعبير Regexp.new(Regexp.escape( str ))=~ str مساوية للقيمة true.

التابع try_convert

يُحاول تحويل الوسيط obj إلى كائن من النوع Regexp، باستخدام التابع to_regexp. ثم يعيد التعبير النمطي الناتج، أو nil في حالة تعذر تحويل obj لسبب أو لآخر.

التابع union

يُعيد كائن من النوع Regexp، والذي يمثل اتحاد الأنماط المعطاة، أي أنه سيتطابق مع أي من أجزائه. يمكن أن تكون الأنماط كائنات من النوع Regexp، وفي هذه الحالة سيتم الاحتفاظ بخياراتها، أو يمكن أن تكون سلاسل نصية. إذا لم يتم إعطاء أية أنماط، فسيعيد القيمة /(?!)/. السلوك سيكون غير محدد إذا احتوى أيُّ من الأنماط المعطاة على التقاط (capture).

التابع ==

معامل التساوي - يتساوى تعبيران نمطيان إن كان نماطهما متطابقين، وكان لهما نفس رمز مجموعة الحروف (character set code)، وكانت لهمنا نفس قيمة casefold?‎.

التابع ===

معامل تساوي الحالة (Case Equality) - يُستخدم في العبارات case.

التابع =~

يبحث عن تطابق للتعبير النمطي rxp ضمن str.

التابع casefold?‎

يعيد قيمة راية الحساسية لحالة الأحرف (case-insensitive flag).

التابع encoding

يُعيد كائنًا من النوع Encoding، والذي يمثل ترميز الكائن .

التابع eql?‎

يعيد القيمة true إن التعبير النمطي المعطى مساويًا للتعبير النمطي ، أي إن كان نمطاهما متطابقان، وكان لهما نفس رمز مجموعة الحروف (haracter set code)، وكانت لهما نفس قيمة casefold?‎.

التابع fixed_encoding?‎

يُعيد القيمة false إن كان التعبير النمطي قابلًا للتطبيق على سلسلة نصية ذات ترميز متوافق مع ASCII. أو يعيد true خلاف ذلك.

التابع hash

يعيد رمز تكويد (hash) استنادًا إلى نص وخيارات هذا التعبير النمطي.

التابع inspect

يعيد نسخة نصية منسقة من التعبير النمطي . قد يكون من المفاجئ أن تعلم أن #inspect ينتج في الواقع نسخة طبيعية من السلسلة النصية أكثر حتى من التابع #to_s.

التابع match

يُعيد كائنًا من النوع MatchData يصف المطابقة، أو يعيد nil إذا لم يكن هناك تطابق. هذا يُكافئ استرداد قيمة المتغير الخاص $~ بعد مطابقة عادية. في حال تمرير الوسيط الثاني،، فإنه يحدد الموضع في السلسلة النصية لبدء البحث.

التابع match?‎

يُعيد القيمة true أو false بحسب ما إذا كان التعبير النمطي قد طوبِق أم لا دون تحديث المتغير $~ والمتغيرات الأخرى ذات الصلة. في حال إعطاء الوسيط الثاني، فإنّه يحدد الموضع في السلسلة النصية لبدء البحث.

التابع named_captures

يُعيد قاموسًا (hash) يحتوي معلومات حول الالتقاطات المسماة (named captures) لتتعبير النمطي .

التابع names

يعيد قائمة بأسماء الأجزاء المُلتقطة (captures) على هبئة مصفوفة من سلاسل نصية.

التابع options

يُعيد مجموعة البتات (bits) المقابلة للخيارات المستخدمة عند إنشاء الكائن Regexp (انظر صفحة Regexp::new لمزيد من التفاصيل. لاحظ أنه قد يتم وضع بتات إضافية في الخيارات المُعادة: والتي تُستخدم داخليًا بواسطة في التعبير النمطي. يتم تجاهل هذه البتات الإضافية إذا تم تمرير الخيارات إلى Regexp::new.

التابع source

يعيد السلسلة النصية الأصلية للنمط.

التابع to_s

يُعيد سلسلة نصية تحتوي على التعبير النمطي وخياراته (باستخدام الصياغة (?opts:source)). يمكن إعطاء هذه السلسلة النصية مرة أخرى إلى المُنشئ Regexp::new لإنشاء تعبير نمطي مشابه للتعبير النمطي الأصلي. (لكن مع ذلك، قد لا يعيد المعامل Regexp#== القيمة trueعند مقارنتهما، حيث قد يختلف مصدر التعبير النمطي نفسه، كما يظهر المثال). ينتج التابع Regexp#inspect نسخة ذات مقروئية أفضل بشكل عام للتعبير النمطي.

التابع ~

يبحث عن مطابقة التعبير النمطي في محتويات المتغير $_. وهو مُكافئ للتعبير rxp =~ $_.