مطابقة الأنماط مع التعبيرات المنتظمة
غالبا ما تتطلب معالجة النصوص في قواعد البيانات مطابقة أنماط تتجاوز ما يمكن للمشغل LIKE التعامل معه. توفر التعبيرات النمطية بناء جملة موحد لمطابقة الأنماط المعقدة، والتحقق، وتحويل النص. تتضمن SQL Server 2025 وقواعد بيانات SQL في Microsoft Fabric دعم التعبيرات النمطية من خلال وظائف T-SQL الجديدة.
فكر في سيناريوهات لا LIKE تقصر: التحقق من عناوين البريد الإلكتروني بالتنسيق الصحيح، استخراج أرقام الهواتف بغض النظر عن اختلافات التنسيق، العثور على رموز المنتجات التي تتبع قواعد تسمية محددة، أو اكتشاف أنماط مثل تكرار الأحرف المتتالية. يدعم المشغل LIKE فقط البطاقات البرية البسيطة (% لأي شخص، _ لحرف واحد)، والتي لا يمكنها التعبير عن هذه الأنماط المعقدة.
تحل التعبيرات النمطية هذه القيود من خلال توفير لغة أنماط غنية. مع regex، يمكنك مطابقة نطاقات الأحرف المحددة، وطلب عدد تكرار دقيق، واستخدام التناوب (مطابقة هذا أو ذاك)، والتقاط أجزاء من النص المطابق للاستخراج أو الاستبدال. بمجرد أن تتعلم بناء جملة regex، يمكنك تطبيقه على العديد من لغات البرمجة والأدوات—الأنماط التي تكتبها ل SQL Server تعمل بطريقة مشابهة في بايثون، جافا سكريبت، وأدوات أوامر الأوامر (Python).
فهم أساسيات التعبير النمطي
تستخدم التعبيرات المنتظمة (regex) نحوية نمط لوصف أنماط النص. قبل أن تتعلم وظائف SQL Server، دعنا نراجع هذه المكونات الشائعة في الريجيكس:
| النمط | وصف | مثال على المباراة |
|---|---|---|
. |
أي شخصية واحدة |
a.c تطابق "abc" و "A1C" |
* |
صفر أو أكثر من ما سبقت |
ab*c تطابق "AC"، "abc"، "ABBC" |
+ |
واحد أو أكثر من ما سبق |
ab+c تطابق "abc"و"abbc" لكنها لا تطابق "AC" |
? |
صفر أو واحد من السابقين |
colou?r تطابق "اللون" و "اللون" |
^ |
بداية الوتر |
^Hello مطابقة السلاسل التي تبدأ ب "Hello" |
$ |
نهاية السلسلة |
world$ مطابقة السلاسل التي تنتهي ب "العالم" |
[abc] |
فئة الشخصية |
[aeiou] يتطابق مع أي حرف متحرك |
[^abc] |
فئة الإلغاء |
[^0-9] مطابقة غير الأرقام |
\d |
ديجيت (0-9) |
\d{3} مطابقة لثلاثة أرقام |
\w |
حرف الكلمة |
\w+ تطابق أحرف الكلمة |
{n} |
بالضبط n تكرار |
\d{4} تطابق تماما أربعة أرقام |
{n,m} |
بين n و m الظواهر |
\d{2,4} مطابقات من 2 إلى 4 أرقام |
ملاحظة
تستخدم دوال التعبيرات النمطية في SQL Server بناء جملة regex القياسية ECMAScript . هذا هو نفس البناء الجملة المستخدم في JavaScript والعديد من لغات البرمجة الأخرى، مما يجعل الأنماط قابلة للنقل عبر التقنيات.
أنماط مطابقة مع REGEXP_LIKE
REGEXP_LIKE يعيد 1 (صحيح) إذا كان السلسلة تطابق نمط تعبير منتظم، أو 0 (خطأ) إذا لم يكن كذلك. استخدم هذه الدالة في WHERE الجمل لتصفية الصفوف بناء على أنماط معقدة:
-- Find customers with email addresses from specific domains
SELECT CustomerID, FirstName, LastName, EmailAddress
FROM SalesLT.Customer
WHERE REGEXP_LIKE(EmailAddress, '@(contoso|adventure-works|fabrikam)\.com$') = 1;
التحقق من صيغ البيانات:
-- Find valid US phone numbers (various formats)
SELECT CustomerID, Phone
FROM SalesLT.Customer
WHERE REGEXP_LIKE(Phone, '^\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$') = 1;
-- Validate product numbers match expected format (XX-XXXX)
SELECT ProductID, ProductNumber, Name
FROM SalesLT.Product
WHERE REGEXP_LIKE(ProductNumber, '^[A-Z]{2}-[A-Z0-9]{4,6}$') = 1;
استخدم مطابقة غير حساسة للحروف مع معامل الأعلام:
-- 'i' flag enables case-insensitive matching
SELECT Name
FROM SalesLT.Product
WHERE REGEXP_LIKE(Name, 'frame', 'i') = 1;
نصيحة
استخدامه REGEXP_LIKE للتحقق والتصفية. هذا أكثر كفاءة من استخراج السلاسل الفرعية عندما تحتاج فقط لمعرفة ما إذا كان هناك نمط ما.
استبدال النص ب REGEXP_REPLACE
REGEXP_REPLACE يجد جميع حالات نمط معين ويستبدله بسلسلة محددة. هذه الوظيفة مفيدة لتنظيف البيانات وتوحيد القياس:
-- Standardize phone numbers to (XXX) XXX-XXXX format
SELECT
Phone AS OriginalPhone,
REGEXP_REPLACE(
REGEXP_REPLACE(Phone, '[^\d]', ''), -- First remove all non-digits
'^(\d{3})(\d{3})(\d{4})$',
'($1) $2-$3'
) AS StandardizedPhone
FROM SalesLT.Customer
WHERE Phone IS NOT NULL;
توضح الأمثلة التالية كيفية استخدام مجموعات الالتقاط مع المراجع الخلفية:
-- Swap first and last name
DECLARE @name NVARCHAR(100) = 'Smith, John';
SELECT REGEXP_REPLACE(@name, '^(\w+),\s*(\w+)$', '$2 $1') AS SwappedName;
-- Returns: John Smith
-- Mask credit card numbers (show last 4 digits only)
DECLARE @card NVARCHAR(20) = '4532-1234-5678-9012';
SELECT REGEXP_REPLACE(@card, '\d(?=[\d-]{4,})', '*') AS MaskedCard;
-- Returns: ****-****-****-9012
توضح الأمثلة التالية كيفية تنظيف البيانات وتطبيعه:
-- Remove extra whitespace (multiple spaces to single space)
SELECT REGEXP_REPLACE(Description, '\s+', ' ') AS CleanedDescription
FROM Products;
-- Remove HTML tags
SELECT REGEXP_REPLACE(HtmlContent, '<[^>]+>', '') AS PlainText
FROM WebPages;
استخراج الأوتار الفرعية باستخدام REGEXP_SUBSTR
REGEXP_SUBSTR يستخرج الجزء من السلسلة التي تطابق نمط تعبير منتظم. استخدمها لسحب عناصر بيانات محددة من النص غير المهيكل مثل الأمثلة التالية:
-- Extract domain from email address
SELECT
EmailAddress,
REGEXP_SUBSTR(EmailAddress, '@(.+)$', 1, 1, '', 1) AS Domain
FROM SalesLT.Customer
WHERE EmailAddress IS NOT NULL;
-- Extract the first number from a string
SELECT
ProductNumber,
REGEXP_SUBSTR(ProductNumber, '\d+') AS FirstNumber
FROM SalesLT.Product;
يوضح المثال التالي توقيع الدالة، الذي يتضمن معلمات لمجموعات الظهور والالتقاط:
REGEXP_SUBSTR(source, pattern, start_position, occurrence, flags, capture_group)
ابحث عن مواقع النمط باستخدام REGEXP_INSTR
REGEXP_INSTR يعيد موضع البداية لمطابقة نمط داخل سلسلة. يعيد 0 إذا لم يتم العثور على تطابق، مثل الأمثلة التالية:
-- Find position of first digit in product number
SELECT
ProductNumber,
REGEXP_INSTR(ProductNumber, '\d') AS FirstDigitPosition
FROM SalesLT.Product;
-- Find position of email domain
SELECT
EmailAddress,
REGEXP_INSTR(EmailAddress, '@') AS AtPosition,
REGEXP_INSTR(EmailAddress, '\.[a-z]+$', 1, 1, 0, 'i') AS TldPosition
FROM SalesLT.Customer
WHERE EmailAddress IS NOT NULL;
تكرار أنماط العد مع REGEXP_COUNT
REGEXP_COUNT يعيد عدد مرات ظهور نمط في سلسلة نصية. توضح الأمثلة التالية استخدامه:
-- Count words in a description
SELECT
Name,
REGEXP_COUNT(Name, '\w+') AS WordCount
FROM SalesLT.Product;
-- Count vowels in product names
SELECT
Name,
REGEXP_COUNT(Name, '[aeiou]', 1, 'i') AS VowelCount
FROM SalesLT.Product;
-- Find products with multiple numbers in their name
SELECT Name
FROM SalesLT.Product
WHERE REGEXP_COUNT(Name, '\d+') > 1;
الأوتار المنقسمة مع REGEXP_SPLIT_TO_TABLE
REGEXP_SPLIT_TO_TABLE هي دالة ذات قيمة جدول تقسم السلسلة إلى صفوف بناء على نمط محدد:
-- Split comma-separated values
DECLARE @tags NVARCHAR(200) = 'sql,database,azure,analytics';
SELECT value AS Tag
FROM REGEXP_SPLIT_TO_TABLE(@tags, ',');
-- Split on multiple delimiters (comma, semicolon, or pipe)
DECLARE @data NVARCHAR(200) = 'apple,banana;cherry|date';
SELECT value AS Fruit
FROM REGEXP_SPLIT_TO_TABLE(@data, '[,;|]');
يمكنك دمجها REGEXP_SPLIT_TO_TABLE مع استفسارات أخرى باستخدام CROSS APPLY:
-- Assuming Products table has a Tags column with comma-separated values
SELECT
p.ProductID,
p.Name,
t.value AS Tag
FROM Products AS p
CROSS APPLY REGEXP_SPLIT_TO_TABLE(p.Tags, ',\s*') AS t;
أعد جميع المباريات مع REGEXP_MATCHES
REGEXP_MATCHES هي دالة ذات قيمة جدول تعيد جميع تطابقات الأنماط كصفوف منفصلة:
-- Find all numbers in a string
DECLARE @text NVARCHAR(200) = 'Order 12345 contains 3 items totaling $99.99';
SELECT match_value, match_index
FROM REGEXP_MATCHES(@text, '\d+\.?\d*');
-- Returns: 12345, 3, 99.99
مهم
تتوفر دوال التعبير النمطية في SQL Server 2025 وقواعد بيانات SQL في Microsoft Fabric. بالنسبة لإصدارات SQL Server السابقة، فكر في استخدام وظائف CLR أو معالجة طبقة التطبيق لعمليات regex معقدة.
لمزيد من المعلومات حول دوال التعبيرات المنتظمة، انظر التعبيرات المنتظمة.