كيفية استخدام وحدة التعبير العادي في Python (مطابقة ، بحث ، فرعي ، إلخ.)

اعمال

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

في هذا القسم ، سنشرح أولاً وظائف وطرق وحدة إعادة الوحدة.

  • تجميع أنماط التعبير العادي:compile()
  • كائن المباراة
  • تحقق مما إذا كانت بداية السلسلة متطابقة ، فاستخرج:match()
  • تحقق من وجود مباريات لا تقتصر على البداية:search()
  • تحقق مما إذا كانت السلسلة بأكملها مطابقة:fullmatch()
  • احصل على قائمة بجميع الأجزاء المطابقة:findall()
  • احصل على جميع الأجزاء المتطابقة كمكرر:finditer()
  • استبدل الجزء المطابق:sub()وsubn()
  • تقسيم السلاسل باستخدام أنماط التعبير العادي:split()

بعد ذلك ، سأشرح الأحرف الوصفية (الأحرف الخاصة) والتسلسلات الخاصة للتعبيرات العادية التي يمكن استخدامها في الوحدة النمطية re. بشكل أساسي ، هو بناء جملة التعبير العادي القياسي ، ولكن كن حذرًا بشأن تعيين العلامات (خاصة re.ASCII).

  • أحرف أولية للتعبير العادي ، متواليات خاصة ، ومحاذير في بايثون
  • وضع العلم
    • يقتصر على أحرف ASCII:re.ASCII
    • غير حساس لحالة الأحرف:re.IGNORECASE
    • تطابق بداية ونهاية كل سطر:re.MULTILINE
    • حدد عدة أعلام
  • المباريات الجشعة وغير الجشعة

تجميع نمط التعبير العادي: compile ()

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

تشغيل مع الوظيفة

الأول هو وظيفة.re.match()وre.sub()تتوفر وظائف مثل هذه لأداء الاستخراج والاستبدال والعمليات الأخرى باستخدام أنماط التعبير العادي.

سيتم وصف تفاصيل الوظائف لاحقًا ، ولكن في كل منها ، تكون الوسيطة الأولى هي سلسلة نمط التعبير العادي ، متبوعة بالسلسلة المراد معالجتها وما إلى ذلك. على سبيل المثال ، في re.sub () ، الذي يقوم بالاستبدال ، تكون الوسيطة الثانية هي سلسلة الاستبدال ، والوسيطة الثالثة هي السلسلة المراد معالجتها.

import re

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

m = re.match(r'([a-z]+)@([a-z]+)\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

result = re.sub(r'([a-z]+)@([a-z]+)\.com', 'new-address', s)
print(result)
# new-address, new-address, ccc@zzz.net

لاحظ أن [a-z] في نمط التعبير العادي في هذا المثال يعني أي حرف من a إلى z (أي الأبجدية الصغيرة) ، و + تعني تكرار النمط السابق (في هذه الحالة [a-z]) مرة واحدة أو أكثر. يتطابق [a-z] + مع أي سلسلة تكرر حرفًا أبجديًا صغيرًا أو أكثر.

. هو حرف تعريف (حرف ذو معنى خاص) ويجب إفلاته بشرطة مائلة للخلف.

نظرًا لأن سلاسل نمط التعبير العادي غالبًا ما تستخدم الكثير من الخطوط المائلة العكسية ، فمن الملائم استخدام السلاسل الأولية كما في المثال.

يعمل بطريقة كائن نمط التعبير العادي

الطريقة الثانية لمعالجة التعبيرات العادية في الوحدة النمطية re هي طريقة كائن نمط التعبير العادي.

باستخدام re.compile () ، يمكنك تجميع سلسلة نمط تعبير عادي لإنشاء كائن نمط تعبير عادي.

p = re.compile(r'([a-z]+)@([a-z]+)\.com')

print(p)
# re.compile('([a-z]+)@([a-z]+)\\.com')

print(type(p))
# <class 're.Pattern'>

re.match()وre.sub()على سبيل المثال ، يمكن تنفيذ نفس العملية مثل هذه الوظائف مثل الطرق المطابقة () ، الفرعية () لكائنات التعبير العادي.

m = p.match(s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

result = p.sub('new-address', s)
print(result)
# new-address, new-address, ccc@zzz.net

يتم أيضًا توفير كافة وظائف re.xxx () الموضحة أدناه كطرق لكائن التعبير العادي.

إذا كنت تكرر عملية تستخدم نفس النمط ، فمن الأفضل إنشاء كائن تعبير عادي باستخدام re.compile () واستخدامه.

في نموذج التعليمات البرمجية التالي ، يتم استخدام الوظيفة دون تجميع للراحة ، ولكن إذا كنت تريد استخدام نفس النمط بشكل متكرر ، فمن المستحسن تجميعه مسبقًا وتنفيذه كطريقة لكائن تعبير عادي.

كائن المباراة

match () ، search () ، إلخ. إرجاع كائن مطابق.

s = 'aaa@xxx.com'

m = re.match(r'[a-z]+@[a-z]+\.[a-z]+', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

print(type(m))
# <class 're.Match'>

يتم الحصول على السلسلة والموضع المتطابقين باستخدام الطرق التالية لكائن المطابقة.

  • احصل على موقع المباراة:start()وend()وspan()
  • احصل على السلسلة المتطابقة:group()
  • احصل على السلسلة لكل مجموعة:groups()
print(m.start())
# 0

print(m.end())
# 11

print(m.span())
# (0, 11)

print(m.group())
# aaa@xxx.com

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

m = re.match(r'([a-z]+)@([a-z]+)\.([a-z]+)', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

print(m.groups())
# ('aaa', 'xxx', 'com')

تحقق مما إذا كانت بداية السلسلة متطابقة ، واستخراج: match ()

تُرجع match () كائنًا مطابقًا إذا كانت بداية السلسلة تطابق النمط.

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

تطابق () سيتحقق من البداية فقط. إذا لم تكن هناك سلسلة مطابقة في البداية ، فإنها ترجع بلا.

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

m = re.match(r'[a-z]+@[a-z]+\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

m = re.match(r'[a-z]+@[a-z]+\.net', s)
print(m)
# None

تحقق من وجود تطابقات لا تقتصر على البداية ، واستخرج: بحث ()

مثل match () ، تقوم بإرجاع كائن تطابق إذا كان متطابقًا.

إذا كانت هناك عدة أجزاء متطابقة ، فسيتم إرجاع الجزء الأول المطابق فقط.

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

m = re.search(r'[a-z]+@[a-z]+\.net', s)
print(m)
# <re.Match object; span=(26, 37), match='ccc@zzz.net'>

m = re.search(r'[a-z]+@[a-z]+\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

إذا كنت تريد الحصول على جميع الأجزاء المطابقة ، فاستخدم findall () أو finditer () كما هو موضح أدناه.

تحقق مما إذا كانت السلسلة بأكملها تطابق: fullmatch ()

للتحقق مما إذا كانت السلسلة بأكملها تطابق نمط التعبير العادي ، استخدم fullmatch (). هذا مفيد ، على سبيل المثال ، للتحقق مما إذا كانت السلسلة صالحة كعنوان بريد إلكتروني أم لا.

إذا تطابقت السلسلة بأكملها ، فسيتم إرجاع كائن تطابق.

s = 'aaa@xxx.com'

m = re.fullmatch(r'[a-z]+@[a-z]+\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

في حالة وجود أجزاء غير متطابقة (مطابقات جزئية فقط أو عدم وجود مطابقات على الإطلاق) ، يتم إرجاع لا شيء.

s = '!!!aaa@xxx.com!!!'

m = re.fullmatch(r'[a-z]+@[a-z]+\.com', s)
print(m)
# None

تمت إضافة fullmatch () في Python 3.4. إذا كنت تريد أن تفعل الشيء نفسه في الإصدارات السابقة ، فاستخدم match () وحرف تعريف مطابق $ في النهاية. إذا لم تتطابق السلسلة بأكملها من البداية إلى النهاية ، فإنها تُرجع بلا.

s = '!!!aaa@xxx.com!!!'

m = re.match(r'[a-z]+@[a-z]+\.com$', s)
print(m)
# None

احصل على قائمة بجميع الأجزاء المطابقة: findall ()

تسترجع findall () قائمة بجميع السلاسل الفرعية المتطابقة. لاحظ أن عناصر القائمة لا تتطابق مع الكائنات ولكنها تتطابق مع السلاسل.

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

result = re.findall(r'[a-z]+@[a-z]+\.[a-z]+', s)
print(result)
# ['aaa@xxx.com', 'bbb@yyy.com', 'ccc@zzz.net']

يمكن التحقق من عدد الأجزاء المتطابقة باستخدام الوظيفة المضمنة len () ، والتي تُرجع عدد العناصر في القائمة.

print(len(result))
# 3

يؤدي التجميع باستخدام الأقواس () في نمط تعبير عادي إلى إرجاع قائمة من المجموعات التي تمثل عناصرها سلاسل كل مجموعة. هذا يعادل المجموعات () في كائن المطابقة.

result = re.findall(r'([a-z]+)@([a-z]+)\.([a-z]+)', s)
print(result)
# [('aaa', 'xxx', 'com'), ('bbb', 'yyy', 'com'), ('ccc', 'zzz', 'net')]

يمكن أن تتداخل أقواس المجموعة () ، لذلك إذا كنت تريد الحصول على التطابق بالكامل أيضًا ، فقم فقط بإحاطة التطابق بالكامل بين قوسين ().

result = re.findall(r'(([a-z]+)@([a-z]+)\.([a-z]+))', s)
print(result)
# [('aaa@xxx.com', 'aaa', 'xxx', 'com'), ('bbb@yyy.com', 'bbb', 'yyy', 'com'), ('ccc@zzz.net', 'ccc', 'zzz', 'net')]

إذا لم يتم العثور على تطابق ، يتم إرجاع مجموعة فارغة.

result = re.findall('[0-9]+', s)
print(result)
# []

احصل على جميع الأجزاء المتطابقة كمكرر: finditer ()

يعرض finditer () جميع الأجزاء المتطابقة كمكرر. العناصر ليست سلاسل مثل findall () ، ولكنها تطابق الكائنات ، بحيث يمكنك الحصول على موضع (فهرس) الأجزاء المتطابقة.

لا يمكن طباعة المكرر نفسه باستخدام print () للحصول على محتوياته. إذا كنت تستخدم الوظيفة المضمنة التالية () أو عبارة for ، فيمكنك الحصول على المحتويات واحدة تلو الأخرى.

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

result = re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)
print(result)
# <callable_iterator object at 0x10b0efa90>

print(type(result))
# <class 'callable_iterator'>

for m in result:
    print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
# <re.Match object; span=(13, 24), match='bbb@yyy.com'>
# <re.Match object; span=(26, 37), match='ccc@zzz.net'>

يمكن أيضًا تحويلها إلى قائمة بها قائمة ().

l = list(re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s))
print(l)
# [<re.Match object; span=(0, 11), match='aaa@xxx.com'>, <re.Match object; span=(13, 24), match='bbb@yyy.com'>, <re.Match object; span=(26, 37), match='ccc@zzz.net'>]

print(l[0])
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

print(type(l[0]))
# <class 're.Match'>

print(l[0].span())
# (0, 11)

إذا كنت ترغب في الحصول على موضع جميع الأجزاء المتطابقة ، فإن تدوين فهم القائمة يكون أكثر ملاءمة من list ().

print([m.span() for m in re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)])
# [(0, 11), (13, 24), (26, 37)]

يقوم المكرر بإخراج العناصر بالترتيب. لاحظ أنه إذا حاولت استخراج المزيد من العناصر بعد الوصول إلى النهاية ، فلن يتبقى لك أي شيء.

result = re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)

for m in result:
    print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
# <re.Match object; span=(13, 24), match='bbb@yyy.com'>
# <re.Match object; span=(26, 37), match='ccc@zzz.net'>

print(list(result))
# []

استبدل الأجزاء المطابقة: sub () ، subn ()

باستخدام sub () ، يمكنك استبدال الجزء المطابق بسلسلة أخرى. سيتم إرجاع السلسلة المستبدلة.

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

result = re.sub(r'[a-z]+@[a-z]+\.com', 'new-address', s)
print(result)
# new-address, new-address, ccc@zzz.net

print(type(result))
# <class 'str'>

عند التجميع باستخدام الأقواس () ، يمكن استخدام السلسلة المتطابقة في السلسلة المستبدلة.

بشكل افتراضي ، يتم دعم ما يلي: لاحظ أنه بالنسبة للسلاسل العادية التي ليست سلاسل أولية ، يجب إدراج الشرطة المائلة للخلف قبل الشرطة المائلة للخلف لتخطي الشرطة المائلة للخلف.

\1القوس الأول
\2القوس الثاني
\3القوس الثالث
result = re.sub(r'([a-z]+)@([a-z]+)\.com', r'\1@\2.net', s)
print(result)
# aaa@xxx.net, bbb@yyy.net, ccc@zzz.net

?P<xxx>
إذا قمت بتسمية المجموعة بكتابة هذا في بداية أقواس نمط التعبير العادي ، فيمكنك تحديدها باستخدام الاسم بدلاً من الرقم ، كما هو موضح أدناه.
\g<xxx>

result = re.sub(r'(?P<local>[a-z]+)@(?P<SLD>[a-z]+)\.com', r'\g<local>@\g<SLD>.net', s)
print(result)
# aaa@xxx.net, bbb@yyy.net, ccc@zzz.net

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

result = re.sub(r'[a-z]+@[a-z]+\.com', 'new-address', s, count=1)
print(result)
# new-address, bbb@yyy.com, ccc@zzz.net

تُرجع الدالة subn () مجموعة من السلسلة المستبدلة (مثل القيمة المرجعة لـ sub ()) وعدد الأجزاء المستبدلة (الرقم الذي يطابق النمط).

result = re.subn(r'[a-z]+@[a-z]+\.com', 'new-address', s)
print(result)
# ('new-address, new-address, ccc@zzz.net', 2)

طريقة تحديد الوسيطات هي نفسها sub (). يمكنك استخدام الجزء الذي تم تجميعه بواسطة أقواس ، أو تحديد عدد المعطيات.

result = re.subn(r'(?P<local>[a-z]+)@(?P<SLD>[a-z]+)\.com', r'\g<local>@\g<SLD>.net', s)
print(result)
# ('aaa@xxx.net, bbb@yyy.net, ccc@zzz.net', 2)

result = re.subn(r'[a-z]+@[a-z]+\.com', 'new-address', s, count=1)
print(result)
# ('new-address, bbb@yyy.com, ccc@zzz.net', 1)

تقسيم السلاسل باستخدام أنماط التعبير العادي: Split ()

يقسم Split () السلسلة عند الجزء المطابق للنمط ويعيدها كقائمة.

لاحظ أن التطابقات الأولى والأخيرة ستحتوي على سلاسل فارغة في بداية ونهاية القائمة الناتجة.

s = '111aaa222bbb333'

result = re.split('[a-z]+', s)
print(result)
# ['111', '222', '333']

result = re.split('[0-9]+', s)
print(result)
# ['', 'aaa', 'bbb', '']

تحدد الوسيطة maxsplit الحد الأقصى لعدد الانقسامات (القطع). سيتم تقسيم العد من الجانب الأيسر فقط.

result = re.split('[a-z]+', s, 1)
print(result)
# ['111', '222bbb333']

أحرف أولية للتعبير العادي ، متواليات خاصة ، ومحاذير في بايثون

الأحرف الوصفية الرئيسية للتعبير العادي (الأحرف الخاصة) والتسلسلات الخاصة التي يمكن استخدامها في وحدة Python 3 re هي كما يلي

حرف أولمحتويات
.أي حرف واحد بخلاف السطر الجديد (بما في ذلك السطر الجديد بعلامة DOTALL)
^بداية السلسلة (تطابق أيضًا بداية كل سطر بعلامة MULTILINE)
$نهاية السلسلة (تطابق أيضًا نهاية كل سطر بعلامة MULTILINE)
*كرر النمط السابق أكثر من 0 مرة
+كرر النمط السابق مرة واحدة على الأقل.
?كرر النمط السابق 0 أو 1 مرة
{m}كرر النمط السابق م مرات
{m, n}النمط الأخير.m~nكرر
[]مجموعة من الشخصيات[]يتطابق مع أي من هذه الشخصيات
|أوA|Bيطابق إما النمط A أو B.
تسلسل خاصمحتويات
\dأرقام Unicode العشرية (تقتصر على أرقام ASCII بواسطة علامة ASCII)
\D\dبمعنى عكس هذا.
\sأحرف المسافات البيضاء Unicode (تقتصر على أحرف المسافات البيضاء ASCII بواسطة علامة ASCII)
\S\sبمعنى عكس هذا.
\wأحرف كلمة Unicode والشرطات السفلية (محدودة بأحرف ASCII الأبجدية الرقمية والشرطات السفلية بواسطة علامة ASCII)
\W\wبمعنى عكس هذا.

لم يتم سرد كل منهم في هذا الجدول. انظر الوثائق الرسمية للحصول على قائمة كاملة.

لاحظ أيضًا أن بعض المعاني مختلفة في Python 2.

وضع العلم

كما هو موضح في الجدول أعلاه ، فإن بعض الأحرف الوصفية والتسلسلات الخاصة تغير وضعها وفقًا للعلامة.

يتم هنا تغطية الأعلام الرئيسية فقط. انظر الوثائق الرسمية لبقية.

يقتصر على أحرف ASCII: re.ASCII

\wسيطابق هذا أيضًا كانجي مزدوج البايت ، وأحرف أبجدية رقمية ، وما إلى ذلك افتراضيًا لسلاسل Python 3. إنه لا يكافئ ما يلي لأنه ليس تعبيرًا عاديًا قياسيًا.[a-zA-Z0-9_]

m = re.match(r'\w+', '漢字ABC123')
print(m)
# <re.Match object; span=(0, 11), match='漢字ABC123'>

m = re.match('[a-zA-Z0-9_]+', '漢字ABC123')
print(m)
# None

إذا حددت re.ASCII لأعلام الوسيطات في كل دالة ، أو أضفت العلامة المضمنة التالية إلى بداية سلسلة نمط التعبير العادي ، فستتطابق فقط مع أحرف ASCII (لن تتطابق مع الأحرف اليابانية مزدوجة البايت والأحرف الأبجدية الرقمية ، إلخ. .).
(?a)
في هذه الحالة ، يكون الاثنان التاليان متكافئين.
\w#ERROR![a-zA-Z0-9_]

m = re.match(r'\w+', '漢字ABC123', flags=re.ASCII)
print(m)
# None

m = re.match(r'(?a)\w+', '漢字ABC123')
print(m)
# None

الأمر نفسه ينطبق عند التحويل البرمجي باستخدام re.compile (). استخدم علامات الوسيطة أو الأعلام المضمنة.

p = re.compile(r'\w+', flags=re.ASCII)
print(p)
# re.compile('\\w+', re.ASCII)

print(p.match('漢字ABC123'))
# None

p = re.compile(r'(?a)\w+')
print(p)
# re.compile('(?a)\\w+', re.ASCII)

print(p.match('漢字ABC123'))
# None

ASCII متاح أيضًا بالصيغة القصيرة re. A. يمكنك استخدام أي منهما.

print(re.ASCII is re.A)
# True

\ W ، عكس \ W ، يتأثر أيضًا بـ re.ASCII والإعلام المضمنة.

m = re.match(r'\W+', '漢字ABC123')
print(m)
# None

m = re.match(r'\W+', '漢字ABC123', flags=re.ASCII)
print(m)
# <re.Match object; span=(0, 11), match='漢字ABC123'>

كما هو الحال مع \ w ، يطابق الحرفان التاليان كلاً من الأحرف أحادية البايت ومزدوجة البايت افتراضيًا ، لكنهما يقتصران على الأحرف أحادية البايت إذا تم تحديد re.ASCII أو العلامات المضمنة.

  • تطابق الأرقام\d
  • يطابق مساحة فارغة\s
  • يتطابق مع غير الأرقام\D
  • يطابق أي مسافات.\S
m = re.match(r'\d+', '123')
print(m)
# <re.Match object; span=(0, 3), match='123'>

m = re.match(r'\d+', '123')
print(m)
# <re.Match object; span=(0, 3), match='123'>

m = re.match(r'\d+', '123', flags=re.ASCII)
print(m)
# <re.Match object; span=(0, 3), match='123'>

m = re.match(r'\d+', '123', flags=re.ASCII)
print(m)
# None

m = re.match(r'\s+', ' ')  # full-width space
print(m)
# <re.Match object; span=(0, 1), match='\u3000'>

m = re.match(r'\s+', ' ', flags=re.ASCII)
print(m)
# None

غير حساس لحالة الأحرف:re.IGNORECASE

بشكل افتراضي ، يكون حساسًا لحالة الأحرف. لمطابقة كليهما ، تحتاج إلى تضمين كل من الأحرف الكبيرة والصغيرة في النمط.

re.IGNORECASEإذا تم تحديد ذلك ، فسوف يتطابق مع عدم حساسية حالة الأحرف. تعادل العلامة i في التعبيرات النمطية القياسية.

m = re.match('[a-zA-Z]+', 'abcABC')
print(m)
# <re.Match object; span=(0, 6), match='abcABC'>

m = re.match('[a-z]+', 'abcABC', flags=re.IGNORECASE)
print(m)
# <re.Match object; span=(0, 6), match='abcABC'>

m = re.match('[A-Z]+', 'abcABC', flags=re.IGNORECASE)
print(m)
# <re.Match object; span=(0, 6), match='abcABC'>

يمكنك استخدام أقل من أو يساوي.

  • علم مضمّن(?i)
  • اختصارre.I

تطابق بداية ونهاية كل سطر:re.MULTILINE

^تطابق الأحرف الوصفية في هذا التعبير العادي بداية السلسلة.

بشكل افتراضي ، تتم مطابقة بداية السلسلة بأكملها فقط ، ولكن ما يلي سيتطابق مع بداية كل سطر أيضًا. تعادل العلامة m في التعبيرات النمطية القياسية.
re.MULTILINE

s = '''aaa-xxx
bbb-yyy
ccc-zzz'''

print(s)
# aaa-xxx
# bbb-yyy
# ccc-zzz

result = re.findall('[a-z]+', s)
print(result)
# ['aaa', 'xxx', 'bbb', 'yyy', 'ccc', 'zzz']

result = re.findall('^[a-z]+', s)
print(result)
# ['aaa']

result = re.findall('^[a-z]+', s, flags=re.MULTILINE)
print(result)
# ['aaa', 'bbb', 'ccc']

$يطابق نهاية السلسلة. بشكل افتراضي ، تتم مطابقة نهاية السلسلة بأكملها فقط.
re.MULTILINEإذا حددت هذا ، فسوف يتطابق أيضًا مع نهاية كل سطر.

result = re.findall('[a-z]+$', s)
print(result)
# ['zzz']

result = re.findall('[a-z]+$', s, flags=re.MULTILINE)
print(result)
# ['xxx', 'yyy', 'zzz']

يمكنك استخدام أقل من أو يساوي.

  • علم مضمّن(?m)
  • اختصارre.M

حدد عدة أعلام

|إذا كنت تريد تمكين علامات متعددة في نفس الوقت ، فاستخدم هذا. في حالة العلامات المضمنة ، يجب أن يتبع كل حرف حرف كما هو موضح أدناه.
(?am)

s = '''aaa-xxx
漢漢漢-字字字
bbb-zzz'''

print(s)
# aaa-xxx
# 漢漢漢-字字字
# bbb-zzz

result = re.findall(r'^\w+', s, flags=re.M)
print(result)
# ['aaa', '漢漢漢', 'bbb']

result = re.findall(r'^\w+', s, flags=re.M | re.A)
print(result)
# ['aaa', 'bbb']

result = re.findall(r'(?am)^\w+', s)
print(result)
# ['aaa', 'bbb']

المباريات الجشعة وغير الجشعة

هذه مشكلة عامة في التعبيرات العادية ، وليست مجرد مشكلة في Python ، لكنني سأكتب عنها لأنها تميل إلى التسبب في مشاكل لي.

بشكل افتراضي ، ما يلي هو تطابق جشع ، والذي يتطابق مع أطول سلسلة ممكنة.

  • *
  • +
  • ?
s = 'aaa@xxx.com, bbb@yyy.com'

m = re.match(r'.+com', s)
print(m)
# <re.Match object; span=(0, 24), match='aaa@xxx.com, bbb@yyy.com'>

print(m.group())
# aaa@xxx.com, bbb@yyy.com

ال ؟ بعد ذلك سوف ينتج عنه تطابق ضئيل غير جشع ، يطابق أقصر سلسلة ممكنة.

  • *?
  • +?
  • ??
m = re.match(r'.+?com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

print(m.group())
# aaa@xxx.com

لاحظ أن التطابق الجشع الافتراضي قد يتطابق مع السلاسل غير المتوقعة.