مختبر التعبيرات النمطية
اختبر التعبيرات النمطية على نص وشاهد جميع التطابقات مُبرَّزة
النمط
نص الاختبار
ما هو التعبير النمطي (Regex)؟
التعبير النمطي (regex أو regexp) هو تسلسل من الأحرف يُعرّف نمط بحث. تتيح لك أدوات اختبار regex كتابة نمط وتشغيله على نص تجريبي ورؤية جميع التطابقات مُبرَّزة في الوقت الفعلي. يعود مفهوم التعبيرات النمطية إلى أعمال الرياضي ستيفن كليني في اللغات النمطية خلال الخمسينيات، ثم بنى كين تومبسون أول محرك regex ضمن محرر النصوص QED عام 1968.
يقرأ محرك regex النمطَ من اليسار إلى اليمين، مستهلكًا أحرف المدخلات في محاولة للمطابقة. يستخدم التراجع (backtracking) حين تفشل مطابقة جزئية: يتراجع المحرك ويجرب مسارات بديلة في النمط. بعض المحركات، كـRE2 المستخدم في Go، تتجنب التراجع كليًا عبر تحويل الأنماط إلى آلات حالة محدودة (DFA)، مما يضمن مطابقة خطية الزمن على حساب دعم ميزات كالمراجع الخلفية (back-references).
صياغة regex غير موحدة بالكامل. PCRE (Perl Compatible Regular Expressions) هي النكهة الأكثر شيوعًا، يدعمها PHP ووحدة re في Python وJavaScript مع اختلافات طفيفة. تُعرّف POSIX صياغة أكثر محدودية تستخدمها grep وsed. تبرز هذه الفروق عند نقل الأنماط بين اللغات: فـlookahead يعمل في JavaScript قد لا يُترجَم في محرك RE2 الخاص بـGo.
لماذا تستخدم مختبر regex عبر الإنترنت؟
كتابة regex داخل ملف برمجي تعني الحفظ والتشغيل وفحص الإخراج في كل مرة تعدّل فيها النمط. أداة regex في المتصفح تختصر هذه الحلقة فورًا: تكتب وترى التطابقات.
حالات استخدام مختبر regex
مرجع سريع لصياغة Regex
يغطي الجدول أدناه أكثر رموز regex استخدامًا. هذه الرموز تعمل عبر JavaScript وPython وGo وPHP ومعظم المحركات المتوافقة مع PCRE. الامتدادات الخاصة بكل لغة (كأنماط Python الشرطية أو المجموعات المسمّاة في JavaScript بصياغة \k) مذكورة في قسم أمثلة التعليمات البرمجية.
| النمط | الاسم | الوصف |
|---|---|---|
| . | Any character | Matches any single character except newline (unless s flag is set) |
| \d | Digit | Matches [0-9] |
| \w | Word character | Matches [a-zA-Z0-9_] |
| \s | Whitespace | Matches space, tab, newline, carriage return, form feed |
| \b | Word boundary | Matches the position between a word character and a non-word character |
| ^ | Start of string/line | Matches the start of the input; with m flag, matches start of each line |
| $ | End of string/line | Matches the end of the input; with m flag, matches end of each line |
| * | Zero or more | Matches the preceding token 0 or more times (greedy) |
| + | One or more | Matches the preceding token 1 or more times (greedy) |
| ? | Optional | Matches the preceding token 0 or 1 time |
| {n,m} | Quantifier range | Matches the preceding token between n and m times |
| () | Capturing group | Groups tokens and captures the matched text for back-references |
| (?:) | Non-capturing group | Groups tokens without capturing the matched text |
| (?=) | Positive lookahead | Matches a position followed by the given pattern, without consuming it |
| (?<=) | Positive lookbehind | Matches a position preceded by the given pattern, without consuming it |
| [abc] | Character class | Matches any one of the characters inside the brackets |
| [^abc] | Negated class | Matches any character not inside the brackets |
| | | Alternation | Matches the expression before or after the pipe |
شرح أعلام Regex
الأعلام (تُسمى أيضًا المعدِّلات) تُغيّر طريقة معالجة المحرك للنمط. في JavaScript تُضاف بعد الشرطة المائلة الختامية: /pattern/gi. في Python تُمرَّر كمعامل ثانٍ: re.findall(pattern, text, re.IGNORECASE | re.MULTILINE). ليست جميع الأعلام متاحة في كل لغة.
| العلم | الاسم | السلوك |
|---|---|---|
| g | Global | Find all matches, not just the first one |
| i | Case-insensitive | Letters match both uppercase and lowercase |
| m | Multiline | ^ and $ match start/end of each line, not just the whole string |
| s | Dot-all | . matches newline characters as well |
| u | Unicode | Treat the pattern and subject as a Unicode string; enables \u{FFFF} syntax |
| y | Sticky | Matches only from the lastIndex position in the target string |
أمثلة على التعليمات البرمجية
أمثلة regex عملية في JavaScript وPython وGo وسطر الأوامر. كل مثال يُظهر بناء النمط واستخراج التطابقات والإخراج.
// Match all email addresses in a string
const text = 'Contact us at support@example.com or sales@example.com'
const emailRegex = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g
const matches = text.matchAll(emailRegex)
for (const match of matches) {
console.log(match[0], 'at index', match.index)
}
// → "support@example.com" at index 14
// → "sales@example.com" at index 37
// Named capture groups (ES2018+)
const dateRegex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
const result = '2026-03-30'.match(dateRegex)
console.log(result.groups)
// → { year: "2026", month: "03", day: "30" }
// Replace with a callback
'hello world'.replace(/\b\w/g, c => c.toUpperCase())
// → "Hello World"import re
# Find all IPv4 addresses
text = 'Server 192.168.1.1 responded, fallback to 10.0.0.255'
pattern = r'\b(?:\d{1,3}\.){3}\d{1,3}\b'
matches = re.findall(pattern, text)
print(matches) # → ['192.168.1.1', '10.0.0.255']
# Named groups and match objects
date_pattern = r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})'
m = re.search(date_pattern, 'Released on 2026-03-30')
if m:
print(m.group('year')) # → '2026'
print(m.group('month')) # → '03'
# Compile for repeated use (faster in loops)
compiled = re.compile(r'\b[A-Z][a-z]+\b')
words = compiled.findall('Hello World Foo bar')
print(words) # → ['Hello', 'World', 'Foo']package main
import (
"fmt"
"regexp"
)
func main() {
// Find all matches
re := regexp.MustCompile(`\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}\b`)
text := "Contact support@example.com or sales@example.com"
matches := re.FindAllString(text, -1)
fmt.Println(matches)
// → [support@example.com sales@example.com]
// Named capture groups
dateRe := regexp.MustCompile(`(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})`)
match := dateRe.FindStringSubmatch("2026-03-30")
for i, name := range dateRe.SubexpNames() {
if name != "" {
fmt.Printf("%s: %s\n", name, match[i])
}
}
// → year: 2026
// → month: 03
// → day: 30
// Replace with a function
result := re.ReplaceAllStringFunc(text, func(s string) string {
return "[REDACTED]"
})
fmt.Println(result)
// → Contact [REDACTED] or [REDACTED]
}# Find lines matching an IP address pattern
grep -E '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b' access.log
# Extract email addresses from a file
grep -oE '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' contacts.txt
# Replace dates from YYYY-MM-DD to DD/MM/YYYY using sed
echo "2026-03-30" | sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3\/\2\/\1/'
# → 30/03/2026
# Count matches per file in a directory
grep -rcE 'TODO|FIXME|HACK' src/
# → src/main.js:3
# → src/utils.js:1