التعبيرات العادية في .NET Framework

توفر التعبيرات العادية طريقة فعالة ومرنة وذات كفاءة لمعالجة النص. يمكنك تدوين مطابقة النمط الشاملة للتعبيرات العادية من تحليل كميات كبيرة من النص بسرعة لتبحث عن نمط أحرف معين; والتحقق من صحة النص للتأكد من أنه يطابق نمط معرّف مسبقاً (مثل عنوان البريد إلكتروني); واستخراج وتحرير واستبدال أو حذف نص سلاسل فرعية; وإضافة السلاسل المستخرجة إلي مجموعة من أجل إنشاء تقرير. التعبيرات العادية أداة لا غني عنها في العديد من التطبيقات التي تتعامل مع السلاسل أو التي تقوم بتحليل كتل كبيرة من النص.

كيفية عمل التعبيرات العادية

محور معالجة النص بواسطة التعبيرات العادية هو مشغّل التعبير العادي الذي يتم تمثيله بواسطة الكائن System.Text.RegularExpressions.Regex في .NET Framework . كحد أدنى، تتطلب المعالجة النصية باستخدام عبارات عادية أن يتم توفير مشغّل التعبير العادي مع نوعين من عناصر المعلومات التالية:

  • نمط التعبير العادية ليتم تحديده في النص.

    يتم تعريف التعبير العادي في .NET Framework بواسطة بناء جملة خاص أو اللغة التي تتوافق مع التعابير النظامية 5 Perl وتقوم بإضافة بعض الميزات الإضافية مثل المطابقة من اليمين لليسار. لمزيد من المعلومات، راجع عناصر اللغة العاديه.

  • النص الذي سيتم تحليله من أجل نمط التعبير العادي.

تسمح لك أساليب الفئة Regex بتنفيذ العمليات التالية:

للحصول نظرة عامة حول طراز كائن التعبير العادي, راجع نموذج كائن التعبير العادي.

أمثلة علي التعبيرات العادية

تحتوي الفئة String على عدد من أساليب البحث و الاستبدال لسلسلة التي يمكنك استخدامها عندما تريد تحديد موقع السلاسل الحرفية في سلسلة أكبر. فائدة التعبيرات العادية الأكبر إما عندما تريد أن تحدد موقع أحد السلاسل الفرعية المتعددة في سلسلة أكبر أو عندما تريد أن تقوم بتعريف الأنماط في سلسلة، كما توضح الأمثلة التالية.

المثال الأول: استبدال السلاسل الفرعية

افترض أن قائمة المراسلات تحتوي على أسماء والتي تتضمن بعض الأحيان عنوان (السيد أو السيدة ، الآنسة أو والسيدة) مع الاسم الأول والأخير. إذا لم تكن تريد تضمين العناوين عند إنشاء تسميات المغلف من القائمة يمكنك استخدام التعبير العادي لإزالة العناوين، كما يوضح المثال التالي.

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern As String = "(Mr. |Mrs. |Miss |Ms. )"
      Dim names() As String = { "Mr. Henry Hunt", "Ms. Sara Samuels", _
                                "Abraham Adams", "Ms. Nicole Norris" }
      For Each name As String In names
         Console.WriteLine(Regex.Replace(name, pattern, String.Empty))
      Next                                
   End Sub
End Module
' The example displays the following output:
'    Henry Hunt
'    Sara Samuels
'    Abraham Adams
'    Nicole Norris
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = "(Mr. |Mrs. |Miss |Ms. )";
      string[] names = { "Mr. Henry Hunt", "Ms. Sara Samuels", 
                         "Abraham Adams", "Ms. Nicole Norris" };
      foreach (string name in names)
         Console.WriteLine(Regex.Replace(name, pattern, String.Empty));
   }
}
// The example displays the following output:
//    Henry Hunt
//    Sara Samuels
//    Abraham Adams
//    Nicole Norris

نمط تعبير عادي (Mr. |Mrs. |Miss |Ms. ) matches any occurrence of "Mr. " ، "السيده". ، "الانسه" أو "السيده" . استدعاء الأسلوب Regex.Replace يستبدل السلسلة المتطابقة بـ String.Empty أو بمعنى آخر، فإنه يزيلها من السلسلة الأصلية

المثال الثاني: يحدد الكلمات المكررة

تكرار الكلمات بطريق الخطأ هو الخطأ الشائع الذي يقع فيه الكتّاب. يمكن استعمال التعبير العادي للتعرف على الكلمات المكررة كما هو موضح في المثال التالي.

Imports System.Text.RegularExpressions

Module modMain
   Public Sub Main()
      Dim pattern As String = "\b(\w+?)\s\1\b"
      Dim input As String = "This this is a nice day. What about this? This tastes good. I saw a a dog."
      For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
         Console.WriteLine("{0} (duplicates '{1})' at position {2}", _
                           match.Value, match.Groups(1).Value, match.Index)
      Next
   End Sub
End Module
' The example displays the following output:
'       This this (duplicates 'This)' at position 0
'       a a (duplicates 'a)' at position 66
using System;
using System.Text.RegularExpressions;

public class Class1
{
   public static void Main()
   {
      string pattern = @"\b(\w+?)\s\1\b";
      string input = "This this is a nice day. What about this? This tastes good. I saw a a dog.";
      foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
         Console.WriteLine("{0} (duplicates '{1})' at position {2}", 
                           match.Value, match.Groups[1].Value, match.Index);
   }
}
// The example displays the following output:
//       This this (duplicates 'This)' at position 0
//       a a (duplicates 'a)' at position 66

يمكن تفسير نمط التعبير العادي \b(\w+?)\s\1\b كما يلي:

\b

تبدأ عند حد كلمة.

+w\

تتوافق مع حرف أو أكثر لكلمة. معاً، تقوم بتكوين مجموعة يمكن الإشارة إليه كـ \1.

\s

تطابق حرف المسافة.

\1

تطابق السلسلة الفرعية التي تساوي المجموعة المسماه بـ \1.

\b

تطابق حد كلمة.

يتم استدعاء الأسلوب Regex.Matches مع تعيين خيارات التعبير العادي إلي RegexOptions.IgnoreCase. لذلك، فعملية التطابق غير حساسة لحالة الأحرف ويقوم المثال بتعريف السلسلة الفرعية "هذا هذا" علي أنها تكرار.

لاحظ أن سلسلة الإدخال تتضمن السلسلة الفرعية "هذا. This". ومع ذلك، وبسبب علامة التنقيط المتداخلة، فهي لا تُعرف علي أنها تكرار.

المثال الثالث: بناء تعبير عادي ذو بيانات موروثة حساسة لحالة الأحرف بشكل حيوي

يوضح المثال التالي قوة التعبيرات العادية المدموجة بالمرونة التي توفرها ميزات التعميم في .NET Framework. وهي تستخدم الكائن DateTimeFormatInfo لتحديد تنسيق قيم العملة في البيانات الموروثة للنظام الحالي. ثم تستخدم هذه المعلومات لإنشاء بشكل حيوي التعبير العادي الذي يستخرج قيم العملات من النص. لكل تطابق، تقوم باستخراج المجموعة الفرعية التي تحتوي على السلسلة الرقمية فقط، وتحولها إلى القيمة Decimal، ثم تحسب إجمالي قيد التشغيل.

Imports System.Collections.Generic
Imports System.Globalization
Imports System.Text.RegularExpressions

Public Module Example
   Public Sub Main()
      ' Define text to be parsed.
      Dim input As String = "Office expenses on 2/13/2008:" + vbCrLf + _
                            "Paper (500 sheets)                      $3.95" + vbCrLf + _
                            "Pencils (box of 10)                     $1.00" + vbCrLf + _
                            "Pens (box of 10)                        $4.49" + vbCrLf + _
                            "Erasers                                 $2.19" + vbCrLf + _
                            "Ink jet printer                        $69.95" + vbCrLf + vbCrLf + _
                            "Total Expenses                        $ 81.58" + vbCrLf
      ' Get current culture's DateTimeFormatInfo object.
      Dim nfi As NumberFormatInfo = CultureInfo.CurrentCulture.NumberFormat
      ' Assign needed property values to variables.
      Dim currencySymbol As String = nfi.CurrencySymbol
      Dim symbolPrecedesIfPositive As Boolean = CBool(nfi.CurrencyPositivePattern Mod 2 = 0)
      Dim groupSeparator As String = nfi.CurrencyGroupSeparator
      Dim decimalSeparator As String = nfi.CurrencyDecimalSeparator

      ' Form regular expression pattern.
      Dim pattern As String = Regex.Escape(CStr(IIf(symbolPrecedesIfPositive, currencySymbol, ""))) + _
                              "\s*[-+]?" + "([0-9]{0,3}(" + groupSeparator + "[0-9]{3})*(" + _
                              Regex.Escape(decimalSeparator) + "[0-9]+)?)" + _
                              CStr(IIf(Not symbolPrecedesIfPositive, currencySymbol, "")) 
      Console.WriteLine("The regular expression pattern is: ")
      Console.WriteLine("   " + pattern)      

      ' Get text that matches regular expression pattern.
      Dim matches As MatchCollection = Regex.Matches(input, pattern, RegexOptions.IgnorePatternWhitespace)               
      Console.WriteLine("Found {0} matches. ", matches.Count)

      ' Get numeric string, convert it to a value, and add it to List object.
      Dim expenses As New List(Of Decimal)

      For Each match As Match In matches
         expenses.Add(Decimal.Parse(match.Groups.Item(1).Value))      
      Next

      ' Determine whether total is present and if present, whether it is correct.
      Dim total As Decimal
      For Each value As Decimal In expenses
         total += value
      Next

      If total / 2 = expenses(expenses.Count - 1) Then
         Console.WriteLine("The expenses total {0:C2}.", expenses(expenses.Count - 1))
      Else
         Console.WriteLine("The expenses total {0:C2}.", total)
      End If   
   End Sub
End Module
' The example displays the following output:
'       The regular expression pattern is:
'          \$\s*[-+]?([0-9]{0,3}(,[0-9]{3})*\.?[0-9]+)
'       Found 6 matches.
'       The expenses total $81.58.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      // Define text to be parsed.
      string input = "Office expenses on 2/13/2008:\n" + 
                     "Paper (500 sheets)                      $3.95\n" + 
                     "Pencils (box of 10)                     $1.00\n" + 
                     "Pens (box of 10)                        $4.49\n" + 
                     "Erasers                                 $2.19\n" + 
                     "Ink jet printer                        $69.95\n\n" + 
                     "Total Expenses                        $ 81.58\n"; 

      // Get current culture's DateTimeFormatInfo object.
      NumberFormatInfo nfi = CultureInfo.CurrentCulture.NumberFormat;
      // Assign needed property values to variables.
      string currencySymbol = nfi.CurrencySymbol;
      bool symbolPrecedesIfPositive = nfi.CurrencyPositivePattern % 2 == 0;
      string groupSeparator = nfi.CurrencyGroupSeparator;
      string decimalSeparator = nfi.CurrencyDecimalSeparator;

      // Form regular expression pattern.
      string pattern = Regex.Escape( symbolPrecedesIfPositive ? currencySymbol : "") + 
                       @"\s*[-+]?" + "([0-9]{0,3}(" + groupSeparator + "[0-9]{3})*(" + 
                       Regex.Escape(decimalSeparator) + "[0-9]+)?)" + 
                       (! symbolPrecedesIfPositive ? currencySymbol : ""); 
      Console.WriteLine( "The regular expression pattern is:");
      Console.WriteLine("   " + pattern);      

      // Get text that matches regular expression pattern.
      MatchCollection matches = Regex.Matches(input, pattern, 
                                              RegexOptions.IgnorePatternWhitespace);               
      Console.WriteLine("Found {0} matches.", matches.Count); 

      // Get numeric string, convert it to a value, and add it to List object.
      List<decimal> expenses = new List<Decimal>();

      foreach (Match match in matches)
         expenses.Add(Decimal.Parse(match.Groups[1].Value));      

      // Determine whether total is present and if present, whether it is correct.
      decimal total = 0;
      foreach (decimal value in expenses)
         total += value;

      if (total / 2 == expenses[expenses.Count - 1]) 
         Console.WriteLine("The expenses total {0:C2}.", expenses[expenses.Count - 1]);
      else
         Console.WriteLine("The expenses total {0:C2}.", total);
   }  
}
// The example displays the following output:
//       The regular expression pattern is:
//          \$\s*[-+]?([0-9]{0,3}(,[0-9]{3})*\.?[0-9]+)
//       Found 6 matches.
//       The expenses total $81.58.

على الكمبيوتر الذي بياناته المورثة الحالية إنكليزية - الولايات المتحدة (en-US)، يقوم المثال ببناء بشكل حيوي التعبير العادي \$\s*[-+]?([0-9]{0,3}(,[0-9]{3})*(\.[0-9]+)?). يمكن تفسير نمط التعبير العادي كما يلي:

\$

تبحث عن وجود وحيد لرمز الدولار ($) في سلسلة الإدخال. تتضمن سلسلة نمط التعبير العادي خط مائل عكسي(\) للإشارة إلى أن الرمز دولار سيتم تفسيره حرفياً بدلاً من تفسيره كإرتساء تعبير عادي. (الرمز $ وحده يوضح أن مشغل التعبير العادي يجب أن يحاول بدأ تطابقه في نهاية السلسلة.) لضمان أن رمز عملة البيانات الموروثة الحالي لم يتم تفسيره على أنه رمز تعبير عادي، يستدعي المثال الأسلوب Escape لتجاهل الحرف.

\s*

ابحث عن صفر تكرار أو أكثر لحرف المسافة.

[-+]?

ابحث عن صفر تواجد أو تواجد وحيد لعلامة موجبة أو علامة سالبة.

([0-9]{0,3}(,[0-9]{3})*(\.[0-9]+)?)

الأقواس الخارجية حول هذا التعبير تعرفها علي أنها مجموعة التقاط صواب أو تعبير فرعي. إذا تم العثور على المطابقة، فيمكن استرداد المعلومات حول هذا الجزء من سلسلة التطابق من الكائن الثاني Group الموجود في الكائن GroupCollection والذي تم إرجاعه بواسطة الخاصية Match.Groups. (العنصر الأول في المجموعة يمثل التطابق بأكمله.)

[0-9]{0,3}

ابحث عن من صفر تواجد إلي ثلاثة تواجدات للأرقام العشرية من 0 إلى 9.

(,[0-9]{3})*

ابحث عن صفر تكرار أو أكثر لفاصلة المجموعة متبوعاً بثلاثة أرقام عشرية.

\.

ابحث عن تواجد وحيد من فاصلة الأرقام العشرية.

[0-9]+

ابحث عن رقم عشري واحد أو أكثر.

(\.[0-9]+)?

ابحث عن تواجد صفر أو واحد الفاصل العشري متبوعاً إلى رقم عشري واحد على الأقل.

إذا تم العثور علي كل من هذه الأنماط الفرعية في سلسلة الإدخال، فستنجح المطابقة، والكائن Match الذي يحتوي علي معلومات حول المطابقة سيتم إضافته للكائن MatchCollection.

مواضيع ذات صلة

Title

الوصف

عناصر اللغة العاديه

يوفر معلومات حول مجموعة الأحرف و العوامل و وحدات الإنشاء التي يمكنك استخدامها لتعريف التعبيرات العادية.

نموذج كائن التعبير العادي

يوفر معلومات وأمثلة تعليمات برمجية التي توضح كيفية استخدام فئات التعبيرات العادية.

تفاصيل سلوك التعبير العادي

يوفر معلومات حول قدرات وسلوك التعبيرات العادية في.NET Framework.

أمثلة علي التعبيرات العادية

يوفر أمثلة تعليمات برمجية توضح الاستخدام النموذجي للتعبيرات العادية.

المرجع

System.Text.RegularExpressions

System.Text.RegularExpressions.Regex