re --- عملیات عبارت باقاعده¶
کد منبع: Lib/re/
این ماژول عملیات تطبیق عبارتهای باقاعده، مشابه آنچه در Perl یافت میشود، ارائه میدهد.
هم الگوها و هم رشتههای مورد جستجو میتوانند رشتههای یونیکد (str) و همچنین رشتههای ۸ بیتی (bytes) باشند. با این حال، رشتههای یونیکد و رشتههای ۸ بیتی نمیتوانند با هم ترکیب شوند: یعنی نمیتوانید یک رشته یونیکد را با یک الگوی bytes تطبیق دهید یا برعکس؛ بههمین ترتیب، هنگام درخواست جایگزینی، رشته جایگزین باید از همان نوع الگو و رشته جستجو باشد.
عبارتهای باقاعده از نویسه بکاسلش ('\') برای نشان دادن صورتهای خاص یا برای اجازه دادن به استفاده از نویسههای خاص بدون فعال شدن معنای خاص آنها استفاده میکنند. این امر با استفاده پایتون از همین نویسه برای همین منظور در رشتههای لفظی تداخل دارد؛ برای مثال، برای تطابق با یک بکاسلش لفظی، ممکن است لازم باشد شما '\\\\' را بهعنوان رشته الگو بنویسید، زیرا عبارت باقاعده باید \\ باشد، و هر بکاسلش باید به صورت \\ داخل یک رشته لفظی معمولی پایتون بیان شود. همچنین، توجه داشته باشید که هر دنباله خنثیسازی نامعتبری در استفاده پایتون از بکاسلش در رشتههای لفظی اکنون یک SyntaxWarning تولید میکند و در آینده این به SyntaxError تبدیل خواهد شد. این رفتار حتی اگر آن دنباله خنثیسازی برای یک عبارت باقاعده معتبر باشد، رخ خواهد داد.
راهحل، استفاده از نمادگذاری رشتهی خام پایتون برای الگوهای عبارت باقاعده است؛ بکاسلشها در لفظی رشتهای که پیشوند 'r' دارد، به هیچ شکل خاصی پردازش نمیشوند. بنابراین r"\n" یک رشتهی ۲نویسهای شامل '\' و 'n' است، در حالی که "\n" یک رشتهی ۱نویسهای شامل یک خط جدید است. معمولاً الگوها در کد پایتون با استفاده از همین نمادگذاری رشتهی خام بیان میشوند.
توجه داشته باشید که بیشتر عملیات عبارت باقاعده بهصورت توابع و متدهای سطح ماژول بر روی عبارات باقاعده کامپایلشده در دسترس هستند. این توابع میانبرهایی هستند که شما را از کامپایل اولیه یک شیء regex بینیاز میکنند، اما فاقد برخی پارامترهای تنظیم دقیق هستند.
همچنین ملاحظه نمائید
ماژول شخص ثالث regex که API سازگار با ماژول re کتابخانه استاندارد دارد، اما قابلیتهای بیشتر و پشتیبانی جامعتر از یونیکد ارائه میدهد.
سینتکس عبارت باقاعده¶
یک عبارت باقاعده (یا RE) مجموعهای از رشتهها را مشخص میکند که با آن مطابقت دارند؛ توابع این ماژول به شما امکان میدهند بررسی کنید که آیا یک رشتهی خاص با یک عبارت باقاعدهی دادهشده مطابقت دارد (یا اینکه آیا یک عبارت باقاعدهی دادهشده با یک رشتهی خاص مطابقت دارد، که در نهایت به یک معناست).
میتوان عبارتهای باقاعده را برای تشکیل عبارتهای باقاعدهی جدید به یکدیگر الحاق کرد؛ اگر A و B هر دو عبارت باقاعده باشند، AB نیز یک عبارت باقاعده است. بهطور کلی، اگر رشتهی p با A و رشتهی دیگری مانند q با B مطابقت داشته باشند، رشتهی pq با AB مطابقت خواهد داشت. این موضوع برقرار است، مگر اینکه A یا B شامل عملیات با اولویت پایین باشد؛ شرایط مرزی بین A و B وجود داشته باشد؛ یا ارجاع به گروههای شمارهدار داشته باشد. بنابراین، میتوان عبارتهای پیچیده را بهآسانی از عبارتهای اولیهی سادهتر، مانند آنچه در اینجا توصیف شد، ساخت. برای جزئیات نظریه و پیادهسازی عبارتهای باقاعده، به کتاب Friedl [Frie09] یا تقریباً هر کتاب درسی دربارهی ساخت کامپایلر مراجعه کنید.
در ادامه توضیح مختصری از قالب عبارتهای باقاعده آمده است. برای اطلاعات بیشتر و ارائهای سادهتر، به راهنمای عبارت باقاعده مراجعه کنید.
عبارات باقاعده میتوانند شامل نویسههای خاص و عادی باشند. بیشتر نویسههای عادی، مانند 'A'، 'a' یا '0'، سادهترین عبارات باقاعده هستند؛ این نویسهها صرفاً با خودشان مطابقت دارند. شما میتوانید نویسههای عادی را به هم بچسبانید، بنابراین last با رشته 'last' مطابقت دارد. (در ادامهی این بخش، عبارتهای باقاعده را با this special style، معمولاً بدون علامت نقلقول، و رشتههای مورد تطابق را 'in single quotes' مینویسیم.)
برخی نویسهها، مانند '|' یا '('، خاص هستند. نویسههای خاص یا نشاندهندهی کلاسهایی از نویسههای عادی هستند، یا بر نحوهی تفسیر عبارتهای باقاعده اطراف آنها تأثیر میگذارند.
عملگرهای تکرار یا کمیتگذارها (*، +، ?، {m,n} و غیره) را نمیتوان بهصورت مستقیم تودرتو کرد. این کار از بروز ابهام با پسوند تغییردهندهی غیرحریص ? و با سایر تغییردهندهها در پیادهسازیهای دیگر جلوگیری میکند. برای اعمال تکرار دوم بر یک تکرار داخلی، میتوان از پرانتز استفاده کرد. برای مثال، عبارت (?:a{6})* با هر مضربی از ۶ نویسهی 'a' مطابقت میکند.
نویسههای خاص عبارتند از:
.(نقطه.) در حالت پیشفرض، این با هر نویسهای به جز خط جدید مطابقت دارد. اگر پرچم
DOTALLمشخص شده باشد، این با هر نویسهای از جمله خط جدید مطابقت دارد.(?s:.)صرفنظر از پرچمها با هر نویسهای مطابقت دارد.
^(Caret.) با آغاز رشته مطابقت دارد، و در حالت
MULTILINEبلافاصله پس از هر خط جدید نیز مطابقت دارد.
$با پایان رشته یا درست پیش از خط جدید در پایان رشته تطابق مییابد، و در حالت
MULTILINEهمچنین پیش از یک خط جدید نیز تطابق مییابد.fooبا هر دو 'foo' و 'foobar' تطابق مییابد، در حالی که عبارت باقاعدهیfoo$فقط با 'foo' تطابق مییابد. جالبتر آنکه، جستوجویfoo.$در'foo1\nfoo2\n'بهطور عادی با 'foo2' تطابق مییابد، اما در حالتMULTILINEبا 'foo1'؛ جستوجوی یک$تنها در'foo\n'دو تطابق (خالی) پیدا میکند: یکی درست پیش از خط جدید، و دیگری در پایان رشته.
*باعث میشود عبارت باقاعده حاصل، ۰ یا چند تکرار از عبارت باقاعده پیشین را تطبیق دهد، تا هر تعداد تکرار که ممکن است.
ab*با «a»، «ab»، یا «a» که پس از آن هر تعداد «b» آمده باشد تطبیق میکند.
+باعث میشود عبارت باقاعده حاصل با ۱ یا چند تکرار از عبارت باقاعده پیشین مطابقت کند.
ab+با 'a'، که پس از آن هر تعداد غیرصفری از نویسههای 'b' آمده باشد، مطابقت خواهد داشت؛ فقط با 'a' مطابقت نخواهد داشت.
?باعث میشود عبارت باقاعده حاصل با ۰ یا ۱ تکرار از عبارت باقاعده پیشین مطابقت کند.
ab?با 'a' یا 'ab' مطابقت خواهد داشت.
*?,+?,??کمیتگذارهای
'*'،'+'و'?'همگی حریص <greedy> هستند؛ آنها تا حد ممکن بیشترین متن را تطبیق میدهند. گاهی این رفتار مطلوب نیست؛ اگر عبارت باقاعده<.*>در برابر'<a> b <c>'تطبیق داده شود، کل رشته را تطبیق میدهد، نه فقط'<a>'را. افزودن?پس از کمیتگذار باعث میشود تطبیق بهصورت غیرحریص <non-greedy> یا کمینه <minimal> انجام شود؛ تا حد ممکن کمترین تعداد نویسه تطبیق داده خواهد شد. استفاده از عبارت باقاعده<.*?>فقط'<a>'را تطبیق میدهد.
*+,++,?+مانند کمیتگذارهای
'*'،'+'و'?'، آنهایی که'+'به آنها الحاق میشود نیز تا جای ممکن دفعات بیشتری تطابق پیدا میکنند. با این حال، برخلاف کمیتگذارهای حریص واقعی، این کمّیسازها هنگامی که عبارت پس از آنها در تطابق شکست میخورد، اجازهی پسگرد نمیدهند. به اینها کمیتگذارهای تصاحبی <possessive> گفته میشود. برای مثال،a*aبا'aaaa'تطابق پیدا خواهد کرد، زیراa*با هر ۴ نویسهی'a'تطابق پیدا میکند، اما هنگامی که نوبت به آخرین'a'میرسد، عبارت پسگرد میشود تا در نهایتa*در مجموع با ۳ نویسهی'a'تطابق پیدا کند و چهارمین'a'با آخرین'a'تطابق پیدا کند. با این حال، وقتیa*+aبرای تطابق با'aaaa'استفاده میشود،a*+با هر ۴ نویسهی'a'تطابق پیدا میکند، اما هنگامی که آخرین'a'در یافتن هیچ نویسهی بیشتری برای تطابق شکست میخورد، امکان پسگرد عبارت وجود ندارد و بنابراین در تطابق شکست میخورد.x*+،x++وx?+بهترتیب معادل(?>x*)،(?>x+)و(?>x?)هستند.اضافه شده در نسخهی 3.11.
{m}مشخص میکند که دقیقاً m تکرار از عبارت باقاعدهی قبلی باید تطابق یابد؛ تعداد کمتر تطابق باعث میشود کل عبارت باقاعده تطابق نیابد. برای مثال،
a{6}دقیقاً با شش نویسهی'a'تطابق مییابد، اما با پنج نویسه تطابق نمییابد.{m,n}سبب میشود عبارت باقاعدهی حاصل، از m تا n تکرار عبارت باقاعدهی پیشین را تطبیق دهد و تلاش میکند تا حد امکان بیشترین تعداد تکرار را تطبیق دهد. برای مثال،
a{3,5}از ۳ تا ۵ نویسهی'a'را تطبیق میدهد. حذف m کران پایین را صفر تعیین میکند، و حذف n کران بالا را بینهایت تعیین میکند. بهعنوان مثال،a{4,}bبا'aaaab'یا هزار نویسهی'a'و بهدنبال آن یک'b'تطبیق میکند، اما با'aaab'تطبیق نمیکند. کاما نباید حذف شود، در غیر این صورت تغییردهنده با صورت توصیفشدهی پیشین اشتباه گرفته میشود.{m,n}?باعث میشود عبارت باقاعدهی حاصل با m تا n تکرار از عبارت باقاعدهی پیشین تطابق یابد و تلاش میکند با کمترین تعداد تکرار ممکن تطابق یابد. این، نسخهای غیرحریصانه (non-greedy) از کمیتگذار (quantifier) پیشین است. برای مثال، در رشتهی ۶ نویسهای
'aaaaaa'،a{3,5}با ۵ نویسهی'a'تطابق خواهد داشت، در حالی کهa{3,5}?تنها با ۳ نویسه تطابق خواهد داشت.{m,n}+باعث میشود عبارت باقاعده حاصل، از m تا n تکرار عبارت باقاعده پیشین را تطابق دهد و تلاش میکند تا بیشترین تعداد تکرار ممکن را بدون ایجاد هیچ نقطهی پسگردی تطابق دهد. این نسخهی تصاحبی (possessive) کمیتگذار بالا است. برای مثال، در رشتهی ۶ نویسهای
'aaaaaa'،a{3,5}+aaتلاش میکند ۵ نویسه'a'را تطابق دهد، سپس چون به ۲ نویسه'a'دیگر نیاز دارد، به نویسههای بیشتری از آنچه در دسترس است نیاز پیدا میکند و در نتیجه شکست میخورد؛ در حالی کهa{3,5}aaتطابق خواهد یافت، بهطوریکهa{3,5}ابتدا ۵ نویسه را میگیرد، سپس با پسگرد، ۴ نویسه'a'را میگیرد و در نهایت ۲ نویسه'a'پایانی توسطaaپایانی در الگو تطابق داده میشود.x{m,n}+معادل(?>x{m,n})است.اضافه شده در نسخهی 3.11.
\یا نویسههای ویژه را خنثی میکند (به شما امکان میدهد نویسههایی مانند
'*'،'?'و مانند آنها را تطبیق دهید)، یا یک دنبالهی ویژه را نشان میدهد؛ دنبالههای ویژه در ادامه بحث شدهاند.اگر برای بیان الگو از رشته خام استفاده نمیکنید، به یاد داشته باشید که پایتون نیز از بکاسلش بهعنوان دنبالهی خنثیسازی در مقادیر لفظی رشتهای استفاده میکند؛ اگر دنبالهی خنثیسازی توسط پارسر پایتون شناخته نشود، بکاسلش و نویسهی بعدی در رشتهی حاصل گنجانده میشوند. با این حال، اگر پایتون دنبالهی حاصل را بشناسد، بکاسلش باید دو بار تکرار شود. این موضوع پیچیده و درک آن دشوار است، بنابراین اکیداً توصیه میشود برای همهی عبارتها بهجز سادهترین آنها از رشتههای خام استفاده کنید.
[]برای نشان دادن مجموعهای از نویسهها به کار میرود. در یک مجموعه:
نویسهها را میتوان بهصورت جداگانه فهرست کرد، برای مثال
[amk]با'a'،'m'یا'k'مطابقت خواهد داشت.
بازههایی از نویسهها را میتوان با دادن دو نویسه و جدا کردن آنها با یک
'-'مشخص کرد؛ برای مثال[a-z]با هر حرف کوچک ASCII تطابق دارد،[0-5][0-9]با تمام اعداد دورقمی از00تا59تطابق دارد، و[0-9A-Fa-f]با هر رقم مبنای شانزده تطابق دارد. اگر-خنثی شود (مثلاً[a\-z]) یا بهعنوان اولین یا آخرین نویسه قرار گیرد (مثلاً[-a]یا[a-])، با یک'-'بهصورت لفظی تطابق دارد.نویسههای خاص بهجز بکاسلش معنای خاص خود را داخل مجموعهها از دست میدهند. برای مثال،
[(+*)]با هر یک از نویسههای لفظی'('،'+'،'*'یا')'تطابق خواهد داشت.
بکاسلش یا نویسههایی با معنای خاص در یک مجموعه، مانند
'-'،']'،'^'و خود'\\'، خنثی میکند، یا یک دنباله خاص را مشخص میکند که نشاندهندهی یک نویسه، مانند\xa0یا\n، یا یک کلاس نویسه، مانند\wیا\Sاست (که در زیر تعریف شدهاند). توجه داشته باشید که\bیک نویسهی «پسبر» را نشان میدهد، نه یک مرز واژه، همانطور که خارج از یک مجموعه چنین است، و دنبالههای خنثیسازی عددی مانند\1همیشه دنبالههای خنثیسازی مبنای هشت هستند، نه ارجاع به گروهها. دنبالههای خاصی که با یک نویسه مطابقت ندارند، مانند\Aو\z، مجاز نیستند.
نویسههایی که در یک بازه نیستند را میتوان با متمم کردن <complementing> مجموعه تطبیق داد. اگر اولین نویسه مجموعه
'^'باشد، همه نویسههایی که در مجموعه نیستند تطبیق داده خواهند شد. برای مثال،[^5]با هر نویسهای به جز'5'تطبیق مییابد، و[^^]با هر نویسهای به جز'^'تطبیق مییابد. اگر^اولین نویسه مجموعه نباشد، معنای خاصی ندارد.برای تطبیق نویسهی
']'بهصورت لفظی درون یک مجموعه، پیش از آن یک بکاسلش قرار دهید یا آن را در ابتدای مجموعه بگذارید. برای مثال، هر دو عبارت[()[\]{}]و[]()[{}]با کروشهی راست، و همچنین با کروشهی چپ، آکولادها و پرانتزها تطبیق میکنند.
پشتیبانی از مجموعههای تودرتو و عملیات مجموعهای، همانطور که در Unicode Technical Standard #18 آمده است، ممکن است در آینده اضافه شود. این موضوع سینتکس را تغییر خواهد داد؛ بنابراین برای تسهیل این تغییر، در حال حاضر در موارد مبهم یک
FutureWarningپرتاب خواهد شد. این شامل مجموعههایی میشود که با'['لفظی شروع میشوند یا حاوی دنبالههای نویسهای لفظی'--'،'&&'،'~~'و'||'هستند. برای اجتناب از هشدار، آنها را با یک بکاسلش خنثی کنید.
تغییر یافته در نسخهی 3.7: در صورتی که یک مجموعهنویسه شامل ساختارهایی باشد که در آینده از نظر معنایی تغییر خواهند کرد،
FutureWarningپرتاب میشود.
|A|B، که در آن A و B میتوانند عبارتهای باقاعده دلخواهی باشند، عبارت باقاعدهای میسازد که با A یا B منطبق میشود. میتوان تعداد دلخواهی از عبارتهای باقاعده را به همین شکل با'|'از هم جدا کرد. این قابلیت را میتوان درون گروهها نیز به کار برد (در ادامه ببینید). هنگامی که رشته هدف پیمایش میشود، عبارتهای باقاعده جداشده با'|'از چپ به راست آزمایش میشوند. هنگامی که یک الگو بهطور کامل منطبق شود، آن شاخه پذیرفته میشود. این بدان معنا است که همین که A منطبق شود، B دیگر آزمایش نمیشود، حتی اگر منجر به تطبیق کلی طولانیتری شود. به بیان دیگر، عملگر'|'هرگز حریص نیست. برای تطبیق نویسهی لفظی'|'، از\|استفاده کنید، یا آن را درون یک کلاس نویسه قرار دهید، مانند[|].
(...)با هر عبارت باقاعدهای که داخل پرانتز باشد، تطابق دارد و آغاز و پایان یک گروه را مشخص میکند؛ محتویات یک گروه را میتوان پس از انجام یک تطابق بازیابی کرد و بعداً میتوان آن را در رشته با دنباله ویژه
\numberکه در ادامه توضیح داده شده است تطابق داد. برای تطابق مقادیر لفظی'('یا')'، از\(یا\)استفاده کنید، یا آنها را داخل یک کلاس نویسه قرار دهید:[(]،[)].
(?...)این یک نمادگذاری افزونه است (یک
'?'پس از'('در غیر این صورت معنایی ندارد). اولین نویسه پس از'?'تعیین میکند که معنا و سینتکس ادامهی این ساختار چیست. افزونهها معمولاً گروه جدیدی ایجاد نمیکنند؛(?P<name>...)تنها استثنا بر این قاعده است. در ادامه افزونههای پشتیبانیشدهی کنونی آمدهاند.(?aiLmsux)(یک یا چند حرف از مجموعه
'a'،'i'،'L'،'m'،'s'،'u'،'x'.) این گروه با رشته خالی تطابق دارد؛ حروف، پرچمهای متناظر را برای کل عبارت باقاعده تنظیم میکنند:re.A(تطبیق فقط ASCII)re.I(نادیدهگرفتن بزرگی و کوچکی حروف)re.L(وابسته به locale)re.M(چندخطی)re.S(نقطه با همه چیز مطابقت میکند)re.U(تطبیق یونیکد)re.X(حالت توضیحی)
(پرچمها در محتوای ماژول توضیح داده شدهاند.) این موضوع زمانی مفید است که بخواهید پرچمها را بهعنوان بخشی از عبارت باقاعده بگنجانید، بهجای آنکه یک آرگومان پرچم به تابع
re.compile()ارسال کنید. پرچمها باید در ابتدای رشتهی عبارت استفاده شوند.تغییر یافته در نسخهی 3.11: این ساختار فقط میتواند در ابتدای عبارت استفاده شود.
(?:...)نسخهی غیرگیرای پرانتزهای معمولی. با هر عبارت باقاعدهای که داخل پرانتزها باشد، تطابق مییابد، اما نمیتوان زیررشتهی تطابقیافته توسط گروه را پس از انجام تطابق بازیابی کرد یا بعداً در الگو به آن ارجاع داد.
(?aiLmsux-imsx:...)(صفر یا چند نویسه از مجموعهی
'a'،'i'،'L'،'m'،'s'،'u'،'x'، که بهصورت اختیاری پس از آنها'-'و سپس یک یا چند نویسه از'i'،'m'،'s'،'x'آمده است.) این نویسهها پرچمهای متناظر را برای بخشی از عبارت تنظیم یا حذف میکنند:re.A(تطبیق فقط ASCII)re.I(نادیدهگرفتن بزرگی و کوچکی حروف)re.L(وابسته به locale)re.M(چندخطی)re.S(نقطه با همه چیز مطابقت میکند)re.U(تطبیق یونیکد)re.X(حالت توضیحی)
(پرچمها در محتوای ماژول توضیح داده شدهاند.)
نویسههای
'a'،'L'و'u'هنگام استفاده بهعنوان پرچمهای درونخط، مانعالجمع هستند، بنابراین نمیتوان آنها را با هم ترکیب کرد یا پس از'-'آورد. در عوض، وقتی یکی از آنها در یک گروه درونخط ظاهر شود، حالت تطبیق گروه دربرگیرنده را بازنویسی میکند. در الگوهای یونیکد،(?a:...)به تطبیق فقط-ASCII تغییر حالت میدهد و(?u:...)به تطبیق یونیکد تغییر حالت میدهد (پیشفرض). در الگوهای بایتی،(?L:...)به تطبیق وابسته به تنظیمات locale تغییر حالت میدهد و(?a:...)به تطبیق فقط-ASCII تغییر حالت میدهد (پیشفرض). این بازنویسی فقط برای گروه درونخط محدود اعمال میشود و حالت تطبیق اصلی خارج از گروه بازیابی میشود.اضافه شده در نسخهی 3.6.
تغییر یافته در نسخهی 3.7: حروف
'a'،'L'و'u'نیز میتوانند در یک گروه استفاده شوند.(?>...)تلاش میکند
...را طوری تطبیق دهد که گویی یک عبارت باقاعده جداگانه است، و اگر موفق شود، به تطبیق بقیه الگوی پس از آن ادامه میدهد. اگر الگوی بعدی در تطبیق شکست بخورد، پشته فقط میتواند تا نقطهای پیش از(?>...)باز شود، زیرا پس از خروج از آن، این عبارت، که بهعنوان یک گروه اتمی <atomic group> (atomic group) شناخته میشود، تمام نقاط پشته درون خود را دور انداخته است. بنابراین،(?>.*).هرگز نمیتواند چیزی را تطبیق دهد، زیرا ابتدا.*تمام نویسههای ممکن را تطبیق میدهد، سپس وقتی دیگر چیزی برای تطبیق باقی نمانده باشد،.پایانی در تطبیق شکست میخورد. از آنجا که هیچ نقطه پشتهای در گروه اتمی ذخیره نشده است و هیچ نقطه پشتهای پیش از آن وجود ندارد، در نتیجه کل عبارت در تطبیق شکست میخورد.اضافه شده در نسخهی 3.11.
(?P<name>...)مشابه پرانتزهای معمولی، اما زیررشتهای که توسط گروه تطبیق داده میشود از طریق نام نمادین گروه name قابل دسترسی است. نامهای گروه باید شناسههای معتبر پایتون باشند، و در الگوهای
bytesفقط میتوانند شامل بایتهایی در محدوده ASCII باشند. هر نام گروه باید فقط یک بار درون یک عبارت باقاعده تعریف شود. یک گروه نمادین همچنین یک گروه شمارهدار است، درست مانند حالتی که گروه نامگذاری نشده باشد.میتوان به گروههای نامدار در سه زمینه ارجاع داد. اگر الگو
(?P<quote>['"]).*?(?P=quote)باشد (یعنی تطبیق رشتهای که با یکی از علامتهای نقلقول تکی یا دوتایی محصور شده است):زمینهی ارجاع به گروه «quote»
راههای ارجاع به آن
در خودِ همان الگو
(?P=quote)(همانطور که نشان داده شده است)\1
هنگام پردازش شیء تطبیق m
m.group('quote')m.end('quote')(و غیره)
در رشتهای که به آرگومان repl از
re.sub()ارسال شده است\g<quote>\g<1>\1
تغییر یافته در نسخهی 3.12: در الگوهای
bytes، نام گروه فقط میتواند شامل بایتهایی در محدوده ASCII (b'\x00'-b'\x7f') باشد.
(?P=name)یک ارجاع به عقب (backreference) به یک گروه نامدار؛ با هر متنی که گروه پیشین با نام name با آن مطابقت کرده است، مطابقت میکند.
(?#...)یک کامنت؛ محتوای پرانتزها بهسادگی نادیده گرفته میشود.
(?=...)در صورتی تطابق مییابد که
...در ادامه تطابق یابد، اما هیچ بخشی از رشته را مصرف نمیکند. این یک ادعای پیشنگر (lookahead assertion) نامیده میشود. برای مثال،Isaac (?=Asimov)تنها در صورتی با'Isaac 'تطابق مییابد که پس از آن'Asimov'آمده باشد.
(?!...)در صورتی مطابقت میکند که
...در ادامه مطابقت نکند. این یک ادعای پیشنگری منفی (negative lookahead assertion) <negative lookahead assertion> است. برای مثال،Isaac (?!Asimov)تنها در صورتی با'Isaac 'مطابقت میکند که پس از آن'Asimov'نیامده باشد.
(?<=...)در صورتی مطابقت میکند که موقعیت فعلی در رشته، بلافاصله پس از یک مطابقت برای
...باشد که در همان موقعیت فعلی پایان مییابد. به این اصطلاح، ادعای پسنگر مثبت (positive lookbehind assertion) گفته میشود.(?<=abc)defیک مطابقت در'abcdef'پیدا میکند، زیرا پسنگر ۳ نویسه به عقب برمیگردد و بررسی میکند که آیا الگوی داخلی مطابقت دارد یا خیر. الگوی داخلی باید فقط با رشتههایی با طول ثابت مطابقت کند، به این معنا کهabcیاa|bمجاز هستند، اماa*وa{3,4}مجاز نیستند. توجه داشته باشید که الگوهایی که با ادعاهای پسنگر مثبت شروع میشوند، در ابتدای رشتهای که جستجو میشود مطابقت نخواهند کرد؛ به احتمال زیاد میخواهید به جای تابعmatch()از تابعsearch()استفاده کنید:>>> import re >>> m = re.search('(?<=abc)def', 'abcdef') >>> m.group(0) 'def'
این مثال به دنبال کلمهای میگردد که پس از خط تیره آمده باشد:
>>> m = re.search(r'(?<=-)\w+', 'spam-egg') >>> m.group(0) 'egg'
تغییر یافته در نسخهی 3.5: پشتیبانی از ارجاعهای گروه با طول ثابت اضافه شد.
(?<!...)در صورتی مطابقت میکند که موقعیت فعلی در رشته، پیش از خود، مطابقتی برای
...نداشته باشد. به این مورد ادعای پسنگر منفی (negative lookbehind assertion) <negative lookbehind assertion> گفته میشود. مانند ادعاهای پسنگر مثبت، الگوی درون آن باید فقط با رشتههایی با طول ثابت مطابقت کند. الگوهایی که با ادعاهای پسنگر منفی آغاز میشوند، ممکن است در ابتدای رشتهی مورد جستجو مطابقت کنند.
(?(id/name)yes-pattern|no-pattern)اگر گروه با id یا name دادهشده وجود داشته باشد، تلاش میشود با
yes-patternتطبیق داده شود، و در غیر این صورت باno-pattern.no-patternاختیاری است و میتوان آن را حذف کرد. برای مثال،(<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$)الگوی تطبیق ایمیل ضعیفی است که هم با'<user@host.com>'و هم با'user@host.com'تطبیق میکند، اما با'<user@host.com'و'user@host.com>'بهطور کامل تطبیق نمیکند (re.search()در مورد نخست فقط'user@host.com'را پیدا میکند).تغییر یافته در نسخهی 3.12: شناسهی گروه id فقط میتواند شامل ارقام ASCII باشد. در الگوهای
bytes، نام گروه name فقط میتواند شامل بایتهایی در محدودهی ASCII (b'\x00'-b'\x7f') باشد.
دنبالههای ویژه شامل '\' و یک نویسه از فهرست زیر هستند. اگر نویسه معمولی یک رقم ASCII یا یک حرف ASCII نباشد، عبارت باقاعده حاصل با دومین نویسه تطابق خواهد داشت. برای مثال، \$ با نویسه '$' تطابق دارد.
\numberبا محتوای گروهی با همان شماره تطابق دارد. شمارهگذاری گروهها از ۱ شروع میشود. برای مثال،
(.+) \1با'the the'یا'55 55'تطابق دارد، اما با'thethe'تطابق ندارد (به فاصله بعد از گروه توجه کنید). این دنباله خاص فقط میتواند برای تطابق با یکی از ۹۹ گروه اول استفاده شود. اگر نخستین رقم number ۰ باشد، یا number ۳ رقم مبنای هشت داشته باشد، بهعنوان تطابق گروهی تفسیر نمیشود، بلکه بهعنوان نویسهای با مقدار مبنای هشت number تفسیر میشود. در داخل'['و']'یک کلاس نویسهای، تمام گریزهای عددی بهعنوان نویسه در نظر گرفته میشوند.
\Aتنها در ابتدای رشته تطابق مییابد.
\bبا رشتهی خالی مطابقت دارد، اما فقط در آغاز یا پایان یک واژه. یک واژه بهعنوان دنبالهای از نویسههای واژه تعریف میشود. توجه داشته باشید که بهصورت رسمی،
\bبهعنوان مرز بین یک نویسهی\wو یک نویسهی\W(یا برعکس)، یا بین\wو آغاز یا پایان رشته تعریف شده است. این یعنیr'\bat\b'با'at'،'at.'،'(at)'و'as at ay'مطابقت دارد، اما با'attempt'یا'atlas'مطابقت ندارد.نویسههای پیشفرض کلمه در الگوهای یونیکد (str)، نویسههای الفبایی و عددی یونیکد و زیرخط هستند، اما میتوان آنها را با استفاده از پرچم
ASCIIتغییر داد. در صورت استفاده از پرچمLOCALE، مرزهای کلمه بر اساس locale فعلی تعیین میشوند.توجه
در داخل یک بازهی نویسه،
\bبرای سازگاری با مقادیر لفظی رشتهای پایتون، نویسهی پسبر را نشان میدهد.
\Bبا رشته خالی تطابق دارد، اما فقط زمانی که در آغاز یا پایان یک کلمه نباشد. این بدان معناست که
r'at\B'با'athens'،'atom'،'attorney'تطابق دارد، اما با'at'،'at.'یا'at!'تطابق ندارد.\Bمخالف\bاست، بنابراین نویسههای کلمه در الگوهای Unicode (str)، نویسههای الفباییعددی Unicode یا نویسهی زیرخط هستند، اگرچه میتوان این را با استفاده از پرچمASCIIتغییر داد. مرزهای کلمه در صورت استفاده از پرچمLOCALEبر اساس تنظیمات locale تعیین میشوند.تغییر یافته در نسخهی 3.14:
\Bاکنون با رشتهی ورودی خالی مطابقت دارد.
\d- برای الگوهای یونیکد (str):
با هر رقم اعشاری یونیکد مطابقت دارد (یعنی هر نویسه در ردهی نویسهای یونیکد [Nd]). این شامل
[0-9]و همچنین بسیاری از نویسههای رقمی دیگر نیز میشود.در صورت استفاده از پرچم
ASCII، با[0-9]مطابقت میکند.- برای الگوهای ۸ بیتی (بایت):
با هر رقم دهدهی در مجموعهنویسهی ASCII مطابقت دارد؛ این معادل
[0-9]است.
\Dبا هر نویسهای که رقم دهدهی نیست، مطابقت میکند. این مخالف
\dاست.در صورت استفاده از پرچم
ASCII، با[^0-9]مطابقت میکند.
\s- برای الگوهای یونیکد (str):
با نویسههای فضای سفید یونیکد (طبق تعریف
str.isspace()) مطابقت دارد. این شامل[ \t\n\r\f\v]و همچنین بسیاری از نویسههای دیگر، برای مثال فاصلههای نشکنی است که قواعد حروفچینی در بسیاری از زبانها آنها را الزامی میدانند.اگر از پرچم
ASCIIاستفاده شود، با[ \t\n\r\f\v]مطابقت دارد.- برای الگوهای ۸ بیتی (بایت):
با نویسههایی که در مجموعه نویسههای ASCII فضای سفید در نظر گرفته میشوند، تطابق دارد؛ این معادل
[ \t\n\r\f\v]است.
\Sبا هر نویسهای که نویسهی فضای خالی نباشد، تطابق مییابد. این متضاد
\sاست.اگر پرچم
ASCIIاستفاده شود، با[^ \t\n\r\f\v]مطابقت دارد.
\w- برای الگوهای یونیکد (str):
با نویسههای واژه در یونیکد مطابقت دارد؛ این شامل تمام نویسههای الفباییعددی یونیکد (طبق تعریف
str.isalnum()) و همچنین زیرخط (_) میشود.در صورت استفاده از پرچم
ASCII، با[a-zA-Z0-9_]مطابقت میکند.- برای الگوهای ۸ بیتی (بایت):
با نویسههایی که در مجموعه نویسههای ASCII الفباییعددی محسوب میشوند، مطابقت دارد؛ این معادل
[a-zA-Z0-9_]است. اگر از پرچمLOCALEاستفاده شود، با نویسههایی که در locale فعلی الفباییعددی محسوب میشوند و نیز با نویسه زیرخط مطابقت دارد.
\Wبا هر نویسهای که نویسه واژگانی نیست، تطابق دارد. این معکوس
\wاست. بهطور پیشفرض، با نویسههای غیر از زیرخط (_) کهstr.isalnum()برای آنهاFalseبرمیگرداند، تطابق دارد.اگر از پرچم
ASCIIاستفاده شود، با[^a-zA-Z0-9_]مطابقت میکند.اگر پرچم
LOCALEاستفاده شود، با نویسههایی مطابقت میکند که در تنظیمات locale جاری، نه الفباییعددی هستند و نه زیرخط.
\zتنها در پایان رشته تطابق میکند.
اضافه شده در نسخهی 3.14.
\Zمشابه
\z. برای سازگاری با نسخههای قدیمی پایتون.
بیشتر دنبالههای خنثیسازی پشتیبانیشده توسط رشتهنوشتههای پایتون، توسط پارسر عبارت باقاعده نیز پذیرفته میشوند:
\a \b \f \n
\N \r \t \u
\U \v \x \\
(توجه داشته باشید که \b برای نمایش مرزهای واژه به کار میرود و تنها در کلاسهای نویسه بهمعنای «پسبر» (backspace) است.)
دنبالههای خنثیسازی '\u'، '\U' و '\N' فقط در الگوهای یونیکد (str) شناسایی میشوند. در الگوهای bytes، این موارد خطا محسوب میشوند. دنبالههای خنثیسازی ناشناختهی حروف ASCII برای استفادهی آینده محفوظ هستند و بهعنوان خطا در نظر گرفته میشوند.
خنثیسازیهای مبنای هشت بهصورت محدودی گنجانده شدهاند. اگر اولین رقم 0 باشد یا سه رقم مبنای هشت وجود داشته باشد، بهعنوان یک خنثیسازی مبنای هشت در نظر گرفته میشود. در غیر این صورت، یک ارجاع به گروه است. مانند رشتههای لفظی، طول خنثیسازیهای مبنای هشت همیشه حداکثر سه رقم است.
تغییر یافته در نسخهی 3.3: دنبالههای خنثیسازی '\u' و '\U' افزوده شدهاند.
تغییر یافته در نسخهی 3.6: خنثیسازیهای ناشناختهای که از '\' و یک حرف ASCII تشکیل شدهاند، اکنون خطا محسوب میشوند.
تغییر یافته در نسخهی 3.8: دنباله خنثیسازی '\N{name}' افزوده شده است. همانند مقادیر لفظی رشته، این دنباله به نویسه یونیکد با نام مشخص بسط مییابد (برای مثال '\N{EM DASH}').
محتوای ماژول¶
این ماژول چندین تابع، چند ثابت و یک استثنا را تعریف میکند. برخی از توابع، نسخههای سادهشدهای از متدهای دارای امکانات کامل برای عبارات باقاعدهی کامپایلشده هستند. بیشتر برنامههای غیربدیهی همیشه از شکل کامپایلشده استفاده میکنند.
پرچمها¶
تغییر یافته در نسخهی 3.6: ثابتهای پرچمی اکنون نمونههایی از RegexFlag هستند که زیرکلاسی از enum.IntFlag است.
- class re.RegexFlag¶
یک کلاس
enum.IntFlagکه شامل گزینههای regex فهرستشده در زیر است.اضافه شده در نسخهی 3.11: - added to
__all__
- re.A¶
- re.ASCII¶
باعث میشود
\w،\W،\b،\B،\d،\D،\sو\Sبهجای تطبیق کامل یونیکد، تطبیق فقط ASCII را انجام دهند. این موضوع فقط برای الگوهای یونیکد (str) معنادار است و برای الگوهای bytes نادیده گرفته میشود.معادل پرچم درونخطی
(?a)است.
- re.DEBUG¶
نمایش اطلاعات اشکالزدایی درباره عبارت کامپایلشده.
پرچم درونخطی متناظری وجود ندارد.
- re.I¶
- re.IGNORECASE¶
تطبیق بدون حساسیت به بزرگی و کوچکی حروف را انجام میدهد؛ عبارتهایی مانند
[A-Z]با حروف کوچک نیز تطبیق میکنند. تطبیق کامل یونیکد (مانند تطبیقÜباü) نیز عمل میکند، مگر اینکه از پرچمASCIIبرای غیرفعال کردن تطبیقهای غیر ASCII استفاده شود. تنظیمات locale فعلی تأثیر این پرچم را تغییر نمیدهد، مگر اینکه از پرچمLOCALEنیز استفاده شود.معادل پرچم درونخطی
(?i)است.توجه داشته باشید که هنگامی که الگوهای یونیکد
[a-z]یا[A-Z]بههمراه پرچمIGNORECASEاستفاده شوند، با ۵۲ حرف ASCII و ۴ حرف غیرASCII دیگر مطابقت خواهند داشت: 'İ' (U+0130، حرف بزرگ لاتین I با نقطه بالا)، 'ı' (U+0131، حرف کوچک لاتین i بدون نقطه)، 'ſ' (U+017F، حرف کوچک لاتین s بلند) و 'K' (U+212A، نماد کلوین). اگر پرچمASCIIاستفاده شود، فقط با حروف 'a' تا 'z' و 'A' تا 'Z' مطابقت داده خواهد شد.
- re.L¶
- re.LOCALE¶
\w،\W،\b،\Bو تطبیق بدون حساسیت به بزرگی و کوچکی حروف را به تنظیمات locale وابسته میکند. این پرچم را فقط میتوان با الگوهای بایتی به کار برد.معادل پرچم درونخطی
(?L)است.هشدار
استفاده از این پرچم توصیه نمیشود؛ در عوض تطبیق یونیکد را در نظر بگیرید. سازوکار تنظیمات locale بسیار غیرقابلاعتماد است، زیرا تنها یک «فرهنگ» را در هر زمان مدیریت میکند و فقط با تنظیمات locale ۸ بیتی کار میکند. تطبیق یونیکد برای الگوهای یونیکد (str) بهطور پیشفرض فعال است و میتواند تنظیمات locale و زبانهای مختلف را مدیریت کند.
تغییر یافته در نسخهی 3.7: اشیای عبارت باقاعدهی کامپایلشده با پرچم
LOCALEدیگر به تنظیمات locale در زمان کامپایل وابسته نیستند. تنها تنظیمات locale در زمان تطبیق بر نتیجهی تطبیق تأثیر میگذارد.
- re.M¶
- re.MULTILINE¶
هنگامی که تعیین شود، نویسهی الگو
'^'در ابتدای رشته و در ابتدای هر خط (بلافاصله پس از هر نویسهی خط جدید) تطابق دارد؛ و نویسهی الگو'$'در انتهای رشته و در انتهای هر خط (بلافاصله پیش از هر نویسهی خط جدید) تطابق دارد. بهطور پیشفرض،'^'فقط در ابتدای رشته تطابق دارد، و'$'فقط در انتهای رشته و بلافاصله پیش از نویسهی خط جدید (در صورت وجود) در انتهای رشته تطابق دارد.معادل پرچم درونخطی
(?m)است.
- re.NOFLAG¶
نشان میدهد که هیچ پرچمی اعمالنشده است؛ مقدار آن
0است. این پرچم میتواند بهعنوان مقدار پیشفرض برای یک آرگومان کلیدواژهای تابع یا بهعنوان مقدار پایهای که بهصورت شرطی با پرچمهای دیگر OR میشود، استفاده شود. نمونهای از استفاده بهعنوان مقدار پیشفرض:def myfunc(text, flag=re.NOFLAG): return re.match(text, flag)
اضافه شده در نسخهی 3.11.
- re.S¶
- re.DOTALL¶
باعث میشود نویسه ویژه
'.'با هر نویسهای، از جمله خط جدید، مطابقت کند؛ بدون این پرچم،'.'با هر چیزی بهجز خط جدید مطابقت میکند.متناظر با پرچم درونخطی
(?s)است.
- re.U¶
- re.UNICODE¶
در Python 3، نویسههای یونیکد بهطور پیشفرض برای الگوهای
strتطبیق داده میشوند. بنابراین این پرچم بیمورد و بدون اثر است و فقط برای سازگاری با نسخههای پیشین نگه داشته شده است.برای محدود کردن تطبیق به نویسههای ASCII، بهجای آن
ASCIIرا ببینید.
- re.X¶
- re.VERBOSE¶
این پرچم به شما امکان میدهد عبارتهای باقاعدهای بنویسید که زیباتر به نظر میرسند و خواناتر هستند؛ زیرا میتوانید بخشهای منطقی الگو را بهصورت بصری از هم جدا کنید و توضیح اضافه کنید. فضای سفید درون الگو نادیده گرفته میشود، مگر وقتی در یک کلاس نویسه باشد، یا وقتی یک بکاسلش خنثینشده پیش از آن آمده باشد، یا درون توکنهایی مانند
*?،(?:یا(?P<...>. برای مثال،(? :و* ?مجاز نیستند. وقتی سطری شامل#باشد که در یک کلاس نویسه نباشد و یک بکاسلش خنثینشده پیش از آن نیامده باشد، تمام نویسهها از چپترین#با این شرایط تا پایان خط نادیده گرفته میشوند.این بدان معناست که دو شیء عبارت باقاعده زیر که با یک عدد دهدهی مطابقت دارند، از نظر عملکردی برابرند:
a = re.compile(r"""\d + # the integral part \. # the decimal point \d * # some fractional digits""", re.X) b = re.compile(r"\d+\.\d*")
متناظر با پرچم درونخطی
(?x)است.
توابع¶
- re.compile(pattern, flags=0)¶
یک الگوی عبارت باقاعده را به یک شیء عبارت باقاعده کامپایل میکند، که میتوان از آن برای تطبیق با استفاده از متدهای
match()،search()و سایر متدهای آن، که در ادامه توضیح داده شدهاند، استفاده کرد.رفتار عبارت را میتوان با تعیین یک مقدار flags تغییر داد. مقادیر میتوانند هر یک از متغیرهای flags باشند و با استفاده از OR بیتی (عملگر
|) ترکیب شوند.دنباله
prog = re.compile(pattern) result = prog.match(string)
معادل است با
result = re.match(pattern, string)
اما استفاده از
re.compile()و ذخیرهی شیء عبارت باقاعدهی حاصل برای استفادهی مجدد، زمانی که عبارت چندین بار در یک برنامه واحد استفاده شود، کارآمدتر است.توجه
نسخههای کامپایلشدهی آخرین الگوهای دادهشده به
re.compile()و به توابع تطبیق در سطح ماژول، در نهانگاه ذخیره میشوند؛ بنابراین برنامههایی که در هر زمان تنها از چند عبارت باقاعده استفاده میکنند، نیازی به نگرانی دربارهی کامپایل کردن عبارات باقاعده ندارند.
- re.search(pattern, string, flags=0)¶
string را پیمایش میکند تا نخستین مکانی را بیابد که عبارت باقاعدهی pattern در آن تطابقی ایجاد میکند، و یک
Matchمتناظر برمیگرداند. اگر هیچ موقعیتی در رشته با الگو تطابق نداشته باشد،Noneبرمیگرداند؛ توجه داشته باشید که این با یافتن یک تطابق به طول صفر در نقطهای از رشته متفاوت است.رفتار عبارت را میتوان با تعیین یک مقدار flags تغییر داد. مقادیر میتوانند هر یک از متغیرهای flags باشند و با استفاده از OR بیتی (عملگر
|) ترکیب شوند.
- re.match(pattern, string, flags=0)¶
اگر صفر یا چند نویسه در ابتدای string با عبارت باقاعدهی pattern تطابق داشته باشند، یک
Matchمتناظر برمیگرداند. اگر رشته با الگو تطابق نداشته باشد،Noneبرمیگرداند؛ توجه داشته باشید که این با یک تطابق با طول صفر متفاوت است.توجه داشته باشید که حتی در حالت
MULTILINE،re.match()فقط در ابتدای رشته تطابق پیدا میکند و نه در ابتدای هر سطر.اگر میخواهید یک تطابق را در هر جای string پیدا کنید، در عوض از
search()استفاده کنید (همچنین search() در مقابل match() را ببینید).رفتار عبارت را میتوان با تعیین یک مقدار flags تغییر داد. مقادیر میتوانند هر یک از متغیرهای flags باشند و با استفاده از OR بیتی (عملگر
|) ترکیب شوند.
- re.fullmatch(pattern, string, flags=0)¶
اگر کل string با عبارت باقاعده pattern تطابق داشته باشد، یک
Matchمتناظر برمیگرداند. اگر رشته با الگو تطابق نداشته باشد،Noneبرمیگرداند؛ توجه داشته باشید که این با تطابق با طول صفر متفاوت است.رفتار عبارت را میتوان با تعیین یک مقدار flags تغییر داد. مقادیر میتوانند هر یک از متغیرهای flags باشند و با استفاده از OR بیتی (عملگر
|) ترکیب شوند.اضافه شده در نسخهی 3.4.
- re.split(pattern, string, maxsplit=0, flags=0)¶
string را بر اساس موارد وقوع pattern تقسیم میکند. اگر در pattern از پرانتزهای ثبتکننده استفاده شود، متن همهی گروههای موجود در الگو نیز بهعنوان بخشی از فهرست حاصل بازگردانده میشود. اگر maxsplit ناصفر باشد، حداکثر maxsplit تقسیم صورت میگیرد و باقیماندهی رشته بهعنوان آخرین عنصر فهرست بازگردانده میشود.
>>> re.split(r'\W+', 'Words, words, words.') ['Words', 'words', 'words', ''] >>> re.split(r'(\W+)', 'Words, words, words.') ['Words', ', ', 'words', ', ', 'words', '.', ''] >>> re.split(r'\W+', 'Words, words, words.', maxsplit=1) ['Words', 'words, words.'] >>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE) ['0', '3', '9']
اگر جداکننده دارای گروههای ثبتکننده باشد و در ابتدای رشته تطابق داشته باشد، نتیجه با یک رشته خالی آغاز میشود. همین حالت برای انتهای رشته نیز صادق است:
>>> re.split(r'(\W+)', '...words, words...') ['', '...', 'words', ', ', 'words', '...', '']
به این ترتیب، کامپوننتهای جداکننده همیشه در اندیسهای نسبی یکسان در فهرست نتیجه یافت میشوند.
امکان تطابقهای خالی مجاور وجود ندارد، اما یک تطابق خالی میتواند بلافاصله پس از یک تطابق غیرخالی رخ دهد.
>>> re.split(r'\b', 'Words, words, words.') ['', 'Words', ', ', 'words', ', ', 'words', '.'] >>> re.split(r'\W*', '...words...') ['', '', 'w', 'o', 'r', 'd', 's', '', ''] >>> re.split(r'(\W*)', '...words...') ['', '...', '', '', 'w', '', 'o', '', 'r', '', 'd', '', 's', '...', '', '', '']
رفتار عبارت را میتوان با تعیین یک مقدار flags تغییر داد. مقادیر میتوانند هر یک از متغیرهای flags باشند و با استفاده از OR بیتی (عملگر
|) ترکیب شوند.تغییر یافته در نسخهی 3.1: آرگومان اختیاری flags افزوده شد.
تغییر یافته در نسخهی 3.7: پشتیبانی از جداسازی بر اساس الگویی که میتواند با رشته خالی مطابقت داشته باشد، اضافه شد.
منسوخ شده از نسخهی 3.13: ارسال maxsplit و flags بهعنوان آرگومانهای جایگاهی منسوخ شده است. در نسخههای آینده پایتون، آنها پارامترهای فقط کلیدواژهای خواهند بود.
- re.findall(pattern, string, flags=0)¶
تمام تطابقهای غیرهمپوشانِ pattern در string را بهصورت فهرستی از رشتهها یا تاپلها برمیگرداند. string از چپ به راست پیمایش میشود و تطابقها به ترتیبی که یافت میشوند، برگردانده میشوند. تطابقهای خالی نیز در نتیجه گنجانده میشوند.
نتیجه به تعداد گروههای ثبتکننده در الگو بستگی دارد. اگر هیچ گروهی وجود نداشته باشد، فهرستی از رشتههای منطبق با کل الگو برمیگرداند. اگر دقیقاً یک گروه وجود داشته باشد، فهرستی از رشتههای منطبق با آن گروه برمیگرداند. اگر چندین گروه وجود داشته باشد، فهرستی از تاپلهایی از رشتههای منطبق با گروهها برمیگرداند. گروههای غیرثبتکننده بر شکل نتیجه تأثیری ندارند.
>>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest') ['foot', 'fell', 'fastest'] >>> re.findall(r'(\w+)=(\d+)', 'set width=20 and height=10') [('width', '20'), ('height', '10')]
رفتار عبارت را میتوان با تعیین یک مقدار flags تغییر داد. مقادیر میتوانند هر یک از متغیرهای flags باشند و با استفاده از OR بیتی (عملگر
|) ترکیب شوند.تغییر یافته در نسخهی 3.7: تطابقهای غیرخالی اکنون میتوانند درست پس از یک تطابق خالی پیشین آغاز شوند.
- re.finditer(pattern, string, flags=0)¶
یک iterator برگردانید که روی همهی تطبیقهای غیرهمپوشان الگوی عبارت باقاعدهی pattern در string، شیءهای
Matchرا تولید میکند. string از چپ به راست پیمایش میشود و تطبیقها به ترتیبی که پیدا میشوند برگردانده میشوند. تطبیقهای خالی نیز در نتیجه گنجانده میشوند.رفتار عبارت را میتوان با تعیین یک مقدار flags تغییر داد. مقادیر میتوانند هر یک از متغیرهای flags باشند و با استفاده از OR بیتی (عملگر
|) ترکیب شوند.تغییر یافته در نسخهی 3.7: تطابقهای غیرخالی اکنون میتوانند درست پس از یک تطابق خالی پیشین آغاز شوند.
- re.sub(pattern, repl, string, count=0, flags=0)¶
رشتهی حاصل از جایگزینی چپترین رخدادهای بدون همپوشانی pattern در string با جایگزین repl را برمیگرداند. اگر pattern یافت نشود، string بدون تغییر برگردانده میشود. repl میتواند یک رشته یا یک تابع باشد؛ اگر رشته باشد، هرگونه دنبالهی خنثیسازی با بکاسلش در آن پردازش میشود. یعنی
\nبه یک نویسهی خط جدید تبدیل میشود،\rبه بازگشت به ابتدای سطر تبدیل میشود، و به همین ترتیب. دنبالههای خنثیسازی ناشناختهی شامل حروف ASCII برای استفادهی آینده محفوظ هستند و بهعنوان خطا تلقی میشوند. سایر دنبالههای خنثیسازی ناشناخته مانند\&بهحال خود باقی میمانند. بازارجاعها (backreferences)، مانند\6، با زیررشتهای که گروه ۶ در الگو آن را تطبیق داده است، جایگزین میشوند. برای مثال:>>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):', ... r'static PyObject*\npy_\1(void)\n{', ... 'def myfunc():') 'static PyObject*\npy_myfunc(void)\n{'
اگر repl یک تابع باشد، برای هر رخداد غیرهمپوشان pattern فراخوانی میشود. این تابع یک آرگومان از نوع
Matchمیگیرد و رشته جایگزینی را برمیگرداند. برای مثال:>>> def dashrepl(matchobj): ... if matchobj.group(0) == '-': return ' ' ... else: return '-' ... >>> re.sub('-{1,2}', dashrepl, 'pro----gram-files') 'pro--gram files' >>> re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE) 'Baked Beans & Spam'
الگو ممکن است یک رشته یا یک
Patternباشد.آرگومان اختیاری count حداکثر تعداد رخدادهای الگو برای جایگزینی است؛ count باید یک عدد صحیح غیرمنفی باشد. اگر حذف شود یا صفر باشد، تمام رخدادهای الگو جایگزین میشوند.
تطبیقهای خالی مجاور امکانپذیر نیستند، اما یک تطبیق خالی میتواند بلافاصله پس از یک تطبیق غیرخالی رخ دهد. در نتیجه،
sub('x*', '-', 'abxd')مقدار'-a-b--d-'را بهجای'-a-b-d-'برمیگرداند.در آرگومانهای repl از نوع رشته، علاوه بر دنبالههای خنثیسازی نویسه و بازارجاعها شرحدادهشده در بالا،
\g<name>از زیررشتهی تطبیقدادهشده با گروهی به نامnameاستفاده خواهد کرد، همانطور که با سینتکس(?P<name>...)تعریف شده است.\g<number>از شمارهی گروه متناظر استفاده میکند؛ بنابراین\g<2>معادل\2است، اما در جایگزینی مانند\g<2>0مبهم نیست.\20بهعنوان ارجاعی به گروه ۲۰ تفسیر میشود، نه ارجاعی به گروه ۲ که پس از آن نویسهی لفظی'0'آمده است. بازارجاع\g<0>با کل زیررشتهی تطبیقدادهشده با RE جایگزین میشود.رفتار عبارت را میتوان با تعیین یک مقدار flags تغییر داد. مقادیر میتوانند هر یک از متغیرهای flags باشند و با استفاده از OR بیتی (عملگر
|) ترکیب شوند.تغییر یافته در نسخهی 3.1: آرگومان اختیاری flags افزوده شد.
تغییر یافته در نسخهی 3.5: گروههای مطابقتنشده با یک رشته خالی جایگزین میشوند.
تغییر یافته در نسخهی 3.6: خنثیسازیهای ناشناخته در pattern که از
'\'و یک حرف ASCII تشکیل شدهاند، اکنون خطا محسوب میشوند.تغییر یافته در نسخهی 3.7: دنبالههای خنثیسازی ناشناخته در repl که از
'\'و یک حرف ASCII تشکیل شدهاند، اکنون خطا هستند. یک تطابق خالی میتواند بلافاصله پس از یک تطابق غیرخالی رخ دهد.تغییر یافته در نسخهی 3.12: شناسهی گروه id فقط میتواند شامل ارقام ASCII باشد. در رشتههای جایگزینی
bytes، نام گروه name فقط میتواند شامل بایتهایی در محدودهی ASCII باشد (b'\x00'-b'\x7f').منسوخ شده از نسخهی 3.13: ارسال count و flags بهعنوان آرگومانهای جایگاهی منسوخ شده است. در نسخههای آینده پایتون، آنها پارامترهای فقط کلیدواژهای خواهند بود.
- re.subn(pattern, repl, string, count=0, flags=0)¶
همان عملیات
sub()را انجام میدهد، اما یک تاپل به شکل(new_string, number_of_subs_made)برمیگرداند.رفتار عبارت را میتوان با تعیین یک مقدار flags تغییر داد. مقادیر میتوانند هر یک از متغیرهای flags باشند و با استفاده از OR بیتی (عملگر
|) ترکیب شوند.
- re.escape(pattern)¶
نویسههای خاص در pattern را خنثی کنید. این کار زمانی مفید است که بخواهید یک رشتهی لفظی دلخواه را تطبیق دهید که ممکن است حاوی نویسههای ویژهی عبارت باقاعده باشد. برای نمونه:
>>> print(re.escape('https://www.python.org')) https://www\.python\.org >>> legal_chars = string.ascii_lowercase + string.digits + "!#$%&'*+-.^_`|~:" >>> print('[%s]+' % re.escape(legal_chars)) [abcdefghijklmnopqrstuvwxyz0123456789!\#\$%\&'\*\+\-\.\^_`\|\~:]+ >>> operators = ['+', '-', '*', '/', '**'] >>> print('|'.join(map(re.escape, sorted(operators, reverse=True)))) /|\-|\+|\*\*|\*
از این تابع نباید برای رشته جایگزین در
sub()وsubn()استفاده شود، فقط بکاسلشها باید خنثی شوند. برای مثال:>>> digits_re = r'\d+' >>> sample = '/usr/sbin/sendmail - 0 errors, 12 warnings' >>> print(re.sub(digits_re, digits_re.replace('\\', r'\\'), sample)) /usr/sbin/sendmail - \d+ errors, \d+ warnings
تغییر یافته در نسخهی 3.3: نویسهی
'_'دیگر خنثی نمیشود.تغییر یافته در نسخهی 3.7: تنها نویسههایی که میتوانند در یک عبارت باقاعده معنای خاصی داشته باشند، خنثی میشوند. در نتیجه،
'!'،'"'،'%'،"'"،','،'/'،':'،';'،'<'،'='،'>'،'@'و"`"دیگر خنثی نمیشوند.
- re.purge()¶
نهانگاه عبارت باقاعده را پاک میکند.
استثناها¶
- exception re.PatternError(msg, pattern=None, pos=None)¶
استثنایی که هنگامی پرتاب میشود که رشتهای به یکی از توابع اینجا داده شود و یک عبارت باقاعده معتبر نباشد (برای مثال، ممکن است شامل پرانتزهای جفتنشده باشد) یا زمانی که خطای دیگری در حین کامپایل یا تطبیق رخ دهد. اگر رشتهای هیچ تطبیقی برای یک الگو نداشته باشد، هرگز خطا محسوب نمیشود. نمونه
PatternErrorدارای ویژگیهای اضافی زیر است:- msg¶
پیام خطای قالببندینشده.
- pattern¶
الگوی عبارت باقاعده.
- pos¶
اندیسی در pattern که کامپایل در آن ناموفق بود (ممکن است
Noneباشد).
- lineno¶
سطر متناظر با pos (ممکن است
Noneباشد).
- colno¶
ستون متناظر با pos (ممکن است
Noneباشد).
تغییر یافته در نسخهی 3.5: ویژگیهای بیشتری اضافه شد.
تغییر یافته در نسخهی 3.13:
PatternErrorدر ابتدا با نامerrorنامگذاری شده بود؛ این نام برای سازگاری با نسخههای پیشین بهعنوان یک نام مستعار حفظ شده است.
اشیای عبارت باقاعده¶
- class re.Pattern¶
شیء عبارت باقاعدهی کامپایلشده که توسط
re.compile()بازگردانده میشود.الگوها نسبت به نوع رشتهای که پردازش میکنند (
strیاbytes) عام هستند.تغییر یافته در نسخهی 3.9:
re.Patternاز[]برای مشخص کردن یک الگوی یونیکد (str) یا بایتی پشتیبانی میکند. Generic Alias Type را ببینید.
- Pattern.search(string[, pos[, endpos]])¶
string را پیمایش میکند تا نخستین مکانی را پیدا کند که این عبارت باقاعده در آن یک تطابق ایجاد میکند، و یک
Matchمتناظر برمیگرداند. اگر هیچ موقعیتی در رشته با الگو تطابق نداشته باشد،Noneبرمیگرداند؛ توجه داشته باشید که این با یافتن یک تطابق با طول صفر در نقطهای از رشته متفاوت است.پارامتر اختیاری دوم pos، اندیسی در رشته را مشخص میکند که جستجو باید از آن آغاز شود؛ مقدار پیشفرض آن
0است. این بهطور کامل معادل اسلایس رشته نیست؛ نویسهی الگوی'^'در آغاز واقعی رشته و در موقعیتهای درست پس از یک خط جدید تطابق دارد، اما نه لزوماً در اندیسی که جستجو باید از آن آغاز شود.پارامتر اختیاری endpos میزان جستجو در رشته را محدود میکند؛ بهطوری که گویی رشته endpos نویسه طول دارد، بنابراین فقط نویسهها از pos تا
endpos - 1برای تطابق جستجو میشوند. اگر endpos کمتر از pos باشد، هیچ تطابقی یافت نخواهد شد؛ در غیر این صورت، اگر rx یک شیء عبارت باقاعده کامپایلشده باشد،rx.search(string, 0, 50)معادلrx.search(string[:50], 0)است.>>> pattern = re.compile("d") >>> pattern.search("dog") # Match at index 0 <re.Match object; span=(0, 1), match='d'> >>> pattern.search("dog", 1) # No match; search doesn't include the "d"
- Pattern.match(string[, pos[, endpos]])¶
اگر این عبارت باقاعده با صفر یا چند نویسه در ابتدای رشته تطابق داشته باشد، یک
Matchمتناظر برمیگرداند. اگر رشته با الگو تطابق نداشته باشد،Noneبرمیگرداند؛ توجه داشته باشید که این با یک تطابق با طول صفر متفاوت است.پارامترهای اختیاری pos و endpos همان معنایی را دارند که برای متد
search()دارند.>>> pattern = re.compile("o") >>> pattern.match("dog") # No match as "o" is not at the start of "dog". >>> pattern.match("dog", 1) # Match as "o" is the 2nd character of "dog". <re.Match object; span=(1, 2), match='o'>
اگر میخواهید تطابقی را در هر جای string بیابید، در عوض از
search()استفاده کنید (همچنین search() در مقابل match() را ببینید).
- Pattern.fullmatch(string[, pos[, endpos]])¶
اگر کل رشته با این عبارت باقاعده تطابق داشته باشد، یک
Matchمتناظر برمیگرداند. اگر رشته با الگو تطابق نداشته باشد،Noneبرمیگرداند؛ توجه داشته باشید که این با یک تطابق با طول صفر متفاوت است.پارامترهای اختیاری pos و endpos همان معنایی را دارند که برای متد
search()دارند.>>> pattern = re.compile("o[gh]") >>> pattern.fullmatch("dog") # No match as "o" is not at the start of "dog". >>> pattern.fullmatch("ogre") # No match as not the full string matches. >>> pattern.fullmatch("doggie", 1, 3) # Matches within given limits. <re.Match object; span=(1, 3), match='og'>
اضافه شده در نسخهی 3.4.
- Pattern.findall(string[, pos[, endpos]])¶
مشابه تابع
findall()است و از الگوی کامپایلشده استفاده میکند، اما پارامترهای اختیاری pos و endpos را نیز میپذیرد که ناحیهی جستجو را مانندsearch()محدود میکنند.
- Pattern.finditer(string[, pos[, endpos]])¶
مشابه تابع
finditer()، از الگوی کامپایلشده استفاده میکند، اما پارامترهای اختیاری pos و endpos را نیز میپذیرد که ناحیه جستجو را مانندsearch()محدود میکنند.
- Pattern.flags¶
پرچمهای تطبیق عبارت باقاعده. این ترکیبی است از پرچمهای دادهشده به
compile()، هر پرچم درونخطی(?...)در الگو، و پرچمهای ضمنی مانندUNICODEدر صورتی که الگو یک رشته یونیکد باشد.
- Pattern.groups¶
تعداد گروههای ثبتکننده (capturing groups) در الگو.
- Pattern.groupindex¶
یک دیکشنری که هر یک از نامهای گروه نمادین تعریفشده با
(?P<id>)را به شمارههای گروه نگاشت میکند. اگر در الگو از هیچ گروه نمادینی استفاده نشده باشد، دیکشنری خالی است.
- Pattern.pattern¶
رشتهی الگویی که شیء الگو از آن کامپایلشده است.
تغییر یافته در نسخهی 3.7: پشتیبانی از copy.copy() و copy.deepcopy() افزوده شد. اشیای عبارت باقاعدهی کامپایلشده، اتمی در نظر گرفته میشوند.
اشیای تطبیق (Match Objects)¶
اشیای Match همیشه مقدار بولی True دارند. از آنجا که match() و search() وقتی هیچ تطبیقی وجود نداشته باشد None برمیگردانند، میتوانید با یک دستور if ساده بررسی کنید که آیا تطبیقی وجود داشته است:
match = re.search(pattern, string)
if match:
process(match)
- class re.Match¶
شیء Match برگرداندهشده توسط فراخوانیهای موفق
matchوsearch.تطبیقها نسبت به نوع رشتهای که تطبیق داده شده است عام هستند (
strیاbytes).تغییر یافته در نسخهی 3.9:
re.Matchاز[]برای مشخص کردن تطبیق یونیکد (str) یا بایت پشتیبانی میکند. Generic Alias Type را ببینید.
- Match.expand(template)¶
رشتهای را برمیگرداند که با انجام جایگزینی بکاسلش روی رشتهی الگو template به دست میآید، همانطور که توسط متد
sub()انجام میشود. دنبالههای خنثیسازی مانند\nبه نویسههای مناسب تبدیل میشوند، و بازارجاعهای عددی (\1،\2) و بازارجاعهای نامدار (\g<1>،\g<name>) با محتوای گروه متناظر جایگزین میشوند. بازارجاع\g<0>با کل تطبیق جایگزین خواهد شد.تغییر یافته در نسخهی 3.5: گروههای مطابقتنشده با یک رشته خالی جایگزین میشوند.
- Match.group([group1, ...])¶
یک یا چند زیرگروه از تطابق را برمیگرداند. اگر تنها یک آرگومان وجود داشته باشد، نتیجه یک رشتهی تنها است؛ اگر چند آرگومان وجود داشته باشد، نتیجه یک تاپل با یک آیتم بهازای هر آرگومان است. بدون آرگومان، group1 بهطور پیشفرض ۰ است (کل تطابق برگردانده میشود). اگر آرگومان groupN برابر ۰ باشد، مقدار بازگشتی متناظر، کل رشتهی مطابقشده است؛ اگر یک عدد صحیح مثبت باشد، رشتهای است که با گروه پرانتزدار متناظر مطابقت دارد. اگر شمارهی گروه منفی یا بزرگتر از تعداد گروههای تعریفشده در الگو باشد، استثنای
IndexErrorپرتاب میشود. اگر گروهی در بخشی از الگو قرار داشته باشد که تطابق نداشته است، نتیجهی متناظرNoneاست. اگر گروهی در بخشی از الگو قرار داشته باشد که چند بار تطابق یافته است، آخرین تطابق برگردانده میشود.>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist") >>> m.group(0) # The entire match 'Isaac Newton' >>> m.group(1) # The first parenthesized subgroup. 'Isaac' >>> m.group(2) # The second parenthesized subgroup. 'Newton' >>> m.group(1, 2) # Multiple arguments give us a tuple. ('Isaac', 'Newton')
اگر عبارت باقاعده از سینتکس
(?P<name>...)استفاده کند، آرگومانهای groupN همچنین میتوانند رشتههایی باشند که گروهها را با نام گروه آنها شناسایی میکنند. اگر یک آرگومان رشتهای بهعنوان نام گروه در الگو استفاده نشود، یک استثنایIndexErrorپرتاب میشود.یک مثال نسبتاً پیچیده:
>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds") >>> m.group('first_name') 'Malcolm' >>> m.group('last_name') 'Reynolds'
همچنین میتوان به گروههای نامدار از طریق اندیس آنها ارجاع داد:
>>> m.group(1) 'Malcolm' >>> m.group(2) 'Reynolds'
اگر یک گروه چندین بار تطابق داشته باشد، تنها آخرین تطابق قابل دسترسی است:
>>> m = re.match(r"(..)+", "a1b2c3") # Matches 3 times. >>> m.group(1) # Returns only the last match. 'c3'
- Match.__getitem__(g)¶
این دقیقاً معادل
m.group(g)است. این کار دسترسی به یک گروه منفرد از یک تطبیق را آسانتر میکند:>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist") >>> m[0] # The entire match 'Isaac Newton' >>> m[1] # The first parenthesized subgroup. 'Isaac' >>> m[2] # The second parenthesized subgroup. 'Newton'
گروههای نامگذاریشده نیز پشتیبانی میشوند:
>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Isaac Newton") >>> m['first_name'] 'Isaac' >>> m['last_name'] 'Newton'
اضافه شده در نسخهی 3.6.
- Match.groups(default=None)¶
یک تاپل حاوی تمام زیرگروههای تطابق، از ۱ تا هر تعداد گروهی که در الگو وجود دارد، برمیگرداند. آرگومان default برای گروههایی استفاده میشود که در تطابق شرکت نکردهاند؛ مقدار پیشفرض آن
Noneاست.برای مثال:
>>> m = re.match(r"(\d+)\.(\d+)", "24.1632") >>> m.groups() ('24', '1632')
اگر نقطه اعشار و همه چیز پس از آن را اختیاری کنیم، ممکن است همه گروهها در تطبیق شرکت نکنند. مقدار پیشفرض این گروهها
Noneخواهد بود، مگر اینکه آرگومان default داده شده باشد:>>> m = re.match(r"(\d+)\.?(\d+)?", "24") >>> m.groups() # Second group defaults to None. ('24', None) >>> m.groups('0') # Now, the second group defaults to '0'. ('24', '0')
- Match.groupdict(default=None)¶
یک دیکشنری شامل تمام زیرگروههای نامدار تطبیق برمیگرداند که کلیدهای آن نام زیرگروهها هستند. آرگومان default برای گروههایی استفاده میشود که در تطبیق شرکت نکردهاند؛ مقدار پیشفرض آن
Noneاست. برای مثال:>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds") >>> m.groupdict() {'first_name': 'Malcolm', 'last_name': 'Reynolds'}
- Match.start([group])¶
- Match.end([group])¶
اندیسهای آغاز و پایان زیررشتهی تطبیقیافته با group را برمیگرداند؛ group بهطور پیشفرض ۰ است (به معنای کل زیررشتهی تطبیقیافته). اگر group وجود داشته باشد اما در تطبیق مشارکت نکرده باشد،
-1را برمیگرداند. برای یک شیء تطبیق m، و گروه g که در تطبیق مشارکت داشته باشد، زیررشتهی تطبیقیافته با گروه g (معادلm.group(g)) عبارت است ازm.string[m.start(g):m.end(g)]
توجه داشته باشید که اگر group با یک رشته خالی تطابق داشته باشد،
m.start(group)باm.end(group)برابر خواهد بود. برای مثال، پس ازm = re.search('b(c?)', 'cba')،m.start(0)برابر ۱ است،m.end(0)برابر ۲ است،m.start(1)وm.end(1)هر دو ۲ هستند وm.start(2)استثنایIndexErrorرا پرتاب میکند.مثالی که remove_this را از نشانیهای ایمیل حذف میکند:
>>> email = "tony@tiremove_thisger.net" >>> m = re.search("remove_this", email) >>> email[:m.start()] + email[m.end():] 'tony@tiger.net'
- Match.span([group])¶
برای یک تطابق m، تاپل دوتایی
(m.start(group), m.end(group))را برمیگرداند. توجه داشته باشید که اگر group در تطابق مشارکت نداشته باشد، این مقدار(-1, -1)خواهد بود. group بهطور پیشفرض صفر است، یعنی کل تطابق.
- Match.pos¶
مقدار pos که به متد
search()یاmatch()یک شیء regex ارسال شده است. این اندیسی در رشته است که موتور RE جستوجو برای یک تطابق را از آن آغاز کرده است.
- Match.endpos¶
مقدار endpos که به متد
search()یاmatch()یک شیء regex ارسال شده است. این اندیسی در رشته است که موتور RE از آن فراتر نخواهد رفت.
- Match.lastindex¶
اندیس عدد صحیح برای آخرین گروه ثبتکننده تطبیقیافته، یا
Noneاگر اصلاً هیچ گروهی تطبیق نیافته باشد. برای مثال، عبارتهای(a)b،((a)(b))و((ab))اگر روی رشته'ab'اعمال شوند، دارایlastindex == 1خواهند بود، در حالی که عبارت(a)(b)اگر روی همان رشته اعمال شود، دارایlastindex == 2خواهد بود.
- Match.lastgroup¶
نام آخرین گروه ثبتکننده (capturing group) تطبیقیافته، یا
Noneاگر آن گروه نامی نداشته باشد، یا اگر اصلاً هیچ گروهی تطبیق داده نشده باشد.
- Match.re¶
شیء عبارت باقاعده که متد
match()یاsearch()آن، این نمونهی تطبیق را تولید کرده است.
تغییر یافته در نسخهی 3.7: پشتیبانی از copy.copy() و copy.deepcopy() افزوده شد. اشیای Match اتمی در نظر گرفته میشوند.
نمونههای عبارت باقاعده¶
بررسی برای یک جفت¶
در این مثال، از تابع کمکی زیر استفاده میکنیم تا اشیای تطبیق (match objects) را کمی مناسبتر نمایش دهیم:
def displaymatch(match):
if match is None:
return None
return '<Match: %r, groups=%r>' % (match.group(), match.groups())
فرض کنید در حال نوشتن یک برنامه پوکر هستید که در آن دست یک بازیکن بهصورت یک رشته ۵ نویسهای نمایش داده میشود و هر نویسه نمایانگر یک کارت است: "a" برای آس، "k" برای شاه، "q" برای بیبی، "j" برای سرباز، "t" برای ۱۰، و "2" تا "9" نمایانگر کارتی با همان مقدار.
برای بررسی اینکه آیا یک رشتهی دادهشده یک دست معتبر است، میتوانید کار زیر را انجام دهید:
>>> valid = re.compile(r"^[a2-9tjqk]{5}$")
>>> displaymatch(valid.match("akt5q")) # Valid.
"<Match: 'akt5q', groups=()>"
>>> displaymatch(valid.match("akt5e")) # Invalid.
>>> displaymatch(valid.match("akt")) # Invalid.
>>> displaymatch(valid.match("727ak")) # Valid.
"<Match: '727ak', groups=()>"
آن دست آخر، "727ak"، شامل یک جفت، یا دو کارت با ارزش یکسان بود. برای تطبیق این موضوع با یک عبارت باقاعده، میتوان از بازارجاعها (backreferences) به این شکل استفاده کرد:
>>> pair = re.compile(r".*(.).*\1")
>>> displaymatch(pair.match("717ak")) # Pair of 7s.
"<Match: '717', groups=('7',)>"
>>> displaymatch(pair.match("718ak")) # No pairs.
>>> displaymatch(pair.match("354aa")) # Pair of aces.
"<Match: '354aa', groups=('a',)>"
برای فهمیدن این که یک جفت از چه کارتی تشکیل شده است، میتوانید از متد group() شیء تطابق به شکل زیر استفاده کنید:
>>> pair = re.compile(r".*(.).*\1")
>>> pair.match("717ak").group(1)
'7'
# Error because re.match() returns None, which doesn't have a group() method:
>>> pair.match("718ak").group(1)
Traceback (most recent call last):
File "<pyshell#23>", line 1, in <module>
re.match(r".*(.).*\1", "718ak").group(1)
AttributeError: 'NoneType' object has no attribute 'group'
>>> pair.match("354aa").group(1)
'a'
شبیهسازی scanf()¶
پایتون در حال حاضر معادلی برای scanf() ندارد. عبارات باقاعده معمولاً از رشتههای قالب scanf() قدرتمندتر هستند، هرچند پرجزئیاتتر نیز میباشند. جدول زیر چند نگاشت کموبیش معادل میان نشانههای قالب scanf() و عبارات باقاعده ارائه میدهد.
توکن |
عبارت باقاعده |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
برای استخراج نام پرونده و اعداد از رشتهای مانند
/usr/sbin/sendmail - 0 errors, 4 warnings
از یک قالب scanf() مانند زیر استفاده میکنید
%s - %d errors, %d warnings
عبارت باقاعده معادل به این صورت خواهد بود
(\S+) - (\d+) errors, (\d+) warnings
search() در مقابل match()¶
پایتون عملیاتهای اولیهی مختلفی را بر پایهی عبارات باقاعده ارائه میدهد:
re.match()وجود تطابق را فقط در ابتدای رشته بررسی میکندre.search()وجود تطابق در هر جای رشته را بررسی میکند (Perl بهطور پیشفرض همین کار را انجام میدهد).re.fullmatch()بررسی میکند که کل رشته تطابق داشته باشد
برای مثال:
>>> re.match("c", "abcdef") # No match
>>> re.search("c", "abcdef") # Match
<re.Match object; span=(2, 3), match='c'>
>>> re.fullmatch("p.*n", "python") # Match
<re.Match object; span=(0, 6), match='python'>
>>> re.fullmatch("r.*n", "python") # No match
عبارتهای باقاعدهای که با '^' شروع میشوند را میتوان همراه با search() برای محدود کردن تطابق به ابتدای رشته استفاده کرد:
>>> re.match("c", "abcdef") # No match
>>> re.search("^c", "abcdef") # No match
>>> re.search("^a", "abcdef") # Match
<re.Match object; span=(0, 1), match='a'>
با این حال توجه داشته باشید که در حالت MULTILINE، match() فقط در ابتدای رشته مطابقت میکند، در حالی که استفاده از search() با عبارت باقاعدهای که با '^' شروع میشود، در ابتدای هر سطر مطابقت خواهد کرد.
>>> re.match("X", "A\nB\nX", re.MULTILINE) # No match
>>> re.search("^X", "A\nB\nX", re.MULTILINE) # Match
<re.Match object; span=(4, 5), match='X'>
ساخت یک دفترچه تلفن¶
split() یک رشته را به فهرستی جداشده با الگوی دادهشده تقسیم میکند. این متد برای تبدیل دادههای متنی به ساختارهای دادهای که بهراحتی توسط پایتون قابل خواندن و اصلاح هستند، بسیار ارزشمند است؛ همانطور که در مثال زیر که یک دفترچه تلفن ایجاد میکند، نشان داده شده است.
ابتدا، ورودی در اینجا آمده است. معمولاً ممکن است از یک پرونده آمده باشد، در اینجا از سینتکس رشته سهنقلقولی استفاده میکنیم
>>> text = """Ross McFluff: 834.345.1254 155 Elm Street
...
... Ronald Heathmore: 892.345.3428 436 Finley Avenue
... Frank Burger: 925.541.7625 662 South Dogwood Way
...
...
... Heather Albrecht: 548.326.4584 919 Park Place"""
مدخلها با یک یا چند سطر جدید از هم جدا شدهاند. اکنون رشته را به فهرستی تبدیل میکنیم که در آن هر خط غیرخالی مدخل جداگانهی خود را دارد:
>>> entries = re.split("\n+", text)
>>> entries
['Ross McFluff: 834.345.1254 155 Elm Street',
'Ronald Heathmore: 892.345.3428 436 Finley Avenue',
'Frank Burger: 925.541.7625 662 South Dogwood Way',
'Heather Albrecht: 548.326.4584 919 Park Place']
در نهایت، هر ورودی را به فهرستی شامل نام، نام خانوادگی، شماره تلفن و نشانی تفکیک کنید. ما از پارامتر maxsplit در split() استفاده میکنیم، زیرا نشانی حاوی فاصلهها، یعنی الگوی تفکیک ما، است:
>>> [re.split(":? ", entry, maxsplit=3) for entry in entries]
[['Ross', 'McFluff', '834.345.1254', '155 Elm Street'],
['Ronald', 'Heathmore', '892.345.3428', '436 Finley Avenue'],
['Frank', 'Burger', '925.541.7625', '662 South Dogwood Way'],
['Heather', 'Albrecht', '548.326.4584', '919 Park Place']]
الگوی :? دونقطهی پس از نام خانوادگی را تطبیق میدهد، بهطوری که این دونقطه در فهرست نتیجه ظاهر نمیشود. با maxsplit برابر 4، میتوانیم شمارهی خانه را از نام خیابان جدا کنیم:
>>> [re.split(":? ", entry, maxsplit=4) for entry in entries]
[['Ross', 'McFluff', '834.345.1254', '155', 'Elm Street'],
['Ronald', 'Heathmore', '892.345.3428', '436', 'Finley Avenue'],
['Frank', 'Burger', '925.541.7625', '662', 'South Dogwood Way'],
['Heather', 'Albrecht', '548.326.4584', '919', 'Park Place']]
دستکاری متن (Munging)¶
sub() هر رخداد از یک الگو را با یک رشته یا نتیجهی یک تابع جایگزین میکند. این مثال استفاده از sub() را با یک تابع برای دگرگونسازی (munge) متن، یا تصادفی کردن ترتیب همهی نویسههای هر واژه از یک جمله بهجز نخستین و آخرین نویسه نشان میدهد:
>>> def repl(m):
... inner_word = list(m.group(2))
... random.shuffle(inner_word)
... return m.group(1) + "".join(inner_word) + m.group(3)
...
>>> text = "Professor Abdolmalek, please report your absences promptly."
>>> re.sub(r"(\w)(\w+)(\w)", repl, text)
'Poefsrosr Aealmlobdk, pslaee reorpt your abnseces plmrptoy.'
>>> re.sub(r"(\w)(\w+)(\w)", repl, text)
'Pofsroser Aodlambelk, plasee reoprt yuor asnebces potlmrpy.'
یافتن همهی قیدها¶
findall() همه رخدادهای یک الگو را تطبیق میدهد، نه فقط اولین رخداد را آنگونه که search() انجام میدهد. برای مثال، اگر نویسندهای بخواهد همه قیدها را در متنی پیدا کند، ممکن است از findall() به شکل زیر استفاده کند:
>>> text = "He was carefully disguised but captured quickly by police."
>>> re.findall(r"\w+ly\b", text)
['carefully', 'quickly']
یافتن همه قیدها و موقعیتهای آنها¶
اگر کسی بخواهد اطلاعات بیشتری دربارهی همهی تطبیقهای یک الگو فراتر از متن تطبیقیافته داشته باشد، finditer() مفید است، زیرا بهجای رشتهها، اشیای Match را فراهم میکند. در ادامهی مثال پیشین، اگر نویسندهای بخواهد همهی قیدها و موقعیتهای آنها را در متنی بیابد، از finditer() به شیوهی زیر استفاده میکند:
>>> text = "He was carefully disguised but captured quickly by police."
>>> for m in re.finditer(r"\w+ly\b", text):
... print('%02d-%02d: %s' % (m.start(), m.end(), m.group(0)))
07-16: carefully
40-47: quickly
نمادگذاری رشته خام¶
نمادگذاری رشتهی خام (r"text") عبارتهای باقاعده را قابلمدیر نگه میدارد. بدون آن، برای خنثی کردن هر بکاسلش ('\') در یک عبارت باقاعده باید پیش از آن یک بکاسلش دیگر قرار داد. برای مثال، دو خط کد زیر از نظر عملکرد یکسان هستند:
>>> re.match(r"\W(.)\1\W", " ff ")
<re.Match object; span=(0, 4), match=' ff '>
>>> re.match("\\W(.)\\1\\W", " ff ")
<re.Match object; span=(0, 4), match=' ff '>
وقتی میخواهید یک بکاسلش لفظی را تطبیق دهید، باید آن را در عبارت باقاعده خنثی کنید. با نمادگذاری رشته خام، این به معنای r"\\" است. بدون نمادگذاری رشته خام، باید از "\\\\" استفاده کنید، که سطرهای کد زیر را از نظر عملکردی یکسان میکند:
>>> re.match(r"\\", r"\\")
<re.Match object; span=(0, 1), match='\\'>
>>> re.match("\\\\", r"\\")
<re.Match object; span=(0, 1), match='\\'>
نوشتن توکنساز (Tokenizer)¶
یک توکنساز (tokenizer) یا اسکنر (scanner) رشتهای را تحلیل میکند تا گروههایی از نویسهها را دستهبندی کند. این نخستین گام مفید در نوشتن یک کامپایلر یا مفسر است.
دستههای متن با عبارات باقاعده مشخص میشوند. روش کار این است که آنها را در یک عبارت باقاعدهی اصلی واحد ترکیب کنید و روی تطابقهای متوالی حلقه بزنید:
from typing import NamedTuple
import re
class Token(NamedTuple):
type: str
value: int | float | str
line: int
column: int
def tokenize(code):
keywords = {'IF', 'THEN', 'ENDIF', 'FOR', 'NEXT', 'GOSUB', 'RETURN'}
token_specification = [
('NUMBER', r'\d+(\.\d*)?'), # Integer or decimal number
('ASSIGN', r':='), # Assignment operator
('END', r';'), # Statement terminator
('ID', r'[A-Za-z]+'), # Identifiers
('OP', r'[+\-*/]'), # Arithmetic operators
('NEWLINE', r'\n'), # Line endings
('SKIP', r'[ \t]+'), # Skip over spaces and tabs
('MISMATCH', r'.'), # Any other character
]
tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specification)
line_num = 1
line_start = 0
for mo in re.finditer(tok_regex, code):
kind = mo.lastgroup
value = mo.group()
column = mo.start() - line_start
if kind == 'NUMBER':
value = float(value) if '.' in value else int(value)
elif kind == 'ID' and value in keywords:
kind = value
elif kind == 'NEWLINE':
line_start = mo.end()
line_num += 1
continue
elif kind == 'SKIP':
continue
elif kind == 'MISMATCH':
raise RuntimeError(f'{value!r} unexpected on line {line_num}')
yield Token(kind, value, line_num, column)
statements = '''
IF quantity THEN
total := total + price * quantity;
tax := price * 0.05;
ENDIF;
'''
for token in tokenize(statements):
print(token)
توکنساز (tokenizer) خروجی زیر را تولید میکند:
Token(type='IF', value='IF', line=2, column=4)
Token(type='ID', value='quantity', line=2, column=7)
Token(type='THEN', value='THEN', line=2, column=16)
Token(type='ID', value='total', line=3, column=8)
Token(type='ASSIGN', value=':=', line=3, column=14)
Token(type='ID', value='total', line=3, column=17)
Token(type='OP', value='+', line=3, column=23)
Token(type='ID', value='price', line=3, column=25)
Token(type='OP', value='*', line=3, column=31)
Token(type='ID', value='quantity', line=3, column=33)
Token(type='END', value=';', line=3, column=41)
Token(type='ID', value='tax', line=4, column=8)
Token(type='ASSIGN', value=':=', line=4, column=12)
Token(type='ID', value='price', line=4, column=15)
Token(type='OP', value='*', line=4, column=21)
Token(type='NUMBER', value=0.05, line=4, column=23)
Token(type='END', value=';', line=4, column=27)
Token(type='ENDIF', value='ENDIF', line=5, column=4)
Token(type='END', value=';', line=5, column=9)
Friedl, Jeffrey. Mastering Regular Expressions. ویرایش سوم، O'Reilly Media، ۲۰۰۹. ویرایش سوم این کتاب دیگر بههیچوجه پایتون را پوشش نمیدهد، اما ویرایش نخست، نوشتن الگوهای خوب عبارت باقاعده را با جزئیات بسیار پوشش میداد.