از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
استفاده از Regex برای دستکاری متن در پایتون
سرفصلهای مطلب
معرفی
پیش پردازش متن یکی از مهمترین وظایف در پردازش زبان طبیعی (NLP) است. به عنوان مثال، ممکن است بخواهید تمام علائم نگارشی را از اسناد متنی حذف کنید تا بتوان از آنها برای طبقه بندی متن استفاده کرد. به طور مشابه، ممکن است بخواهید اعداد را از یک رشته متن استخراج کنید. نوشتن اسکریپت های دستی برای چنین کارهای پیش پردازشی نیاز به تلاش زیادی دارد و مستعد خطا است. با توجه به اهمیت این وظایف پیش پردازش، عبارات با قاعده (معروف به Regex) به زبان های مختلف به منظور سهولت این وظایف پیش پردازش متن توسعه داده شده است.
یک عبارت منظم یک رشته متنی است که یک الگوی جستجو را توصیف می کند که می تواند برای مطابقت یا جایگزینی الگوهای داخل یک رشته با حداقل مقدار کد مورد استفاده قرار گیرد. در این آموزش انواع مختلف عبارات منظم را در زبان پایتون پیاده سازی می کنیم.
برای پیاده سازی عبارات منظم، Python’s re
بسته قابل استفاده است. پایتون را وارد کنید re
بسته با دستور زیر:
import re
جستجوی الگوها در یک رشته
یکی از رایج ترین کارهای NLP این است که جستجو کنید آیا یک رشته دارای الگوی خاصی است یا خیر. به عنوان مثال، ممکن است بخواهید عملیاتی را انجام دهید روی بر اساس رشته روی شرطی که رشته شامل یک عدد باشد.
برای جستجوی یک الگو در یک رشته، match
و findall
عملکرد از re
بسته استفاده می شود.
عملکرد مسابقه
مقدار دهی اولیه یک متغیر text
با یک رشته متن به صورت زیر:
text = "The film Titanic was released in 1998"
بیایید یک عبارت regex بنویسیم که با یک رشته با هر طول و هر کاراکتری مطابقت داشته باشد:
result = re.match(r".*", text)
اولین پارامتر از match
تابع عبارت regex است که می خواهید جستجو کنید. عبارت Regex با حروف الفبا شروع می شود r
به دنبال الگویی که می خواهید جستجو کنید. الگو باید مانند هر رشته دیگری در گیومه های تک یا دوتایی محصور شود.
عبارت regex بالا با رشته متن مطابقت دارد، زیرا ما سعی می کنیم رشته ای با هر طول و هر کاراکتری را مطابقت دهیم. اگر یک مسابقه پیدا شد، match
تابع برمی گردد _sre.SRE_Match
شیء مطابق شکل زیر:
type(result)
خروجی:
_sre.SRE_Match
اکنون برای یافتن رشته منطبق، می توانید از دستور زیر استفاده کنید:
result.group(0)
خروجی:
'The film Titanic was released in 1998'
در صورتی که هیچ مطابقی توسط match
عملکرد، الف null
شی برگردانده می شود.
اکنون عبارت regex قبلی با یک رشته با هر طول و هر کاراکتری مطابقت دارد. همچنین با یک رشته خالی به طول صفر مطابقت دارد. برای آزمایش این، مقدار متغیر متن را با یک رشته خالی به روز کنید:
text = ""
حال، اگر دوباره عبارت regex زیر را اجرا کنید، مطابقت پیدا میشود:
result = re.match(r".*", text)
از آنجایی که ما تعیین کردیم که رشته را با هر طول و هر کاراکتری مطابقت دهیم، حتی یک رشته خالی هم مطابقت دارد.
برای تطبیق رشته ای با طول حداقل 1، از عبارت regex زیر استفاده می شود:
result = re.match(r".+", text)
در اینجا علامت مثبت مشخص می کند که رشته باید حداقل یک کاراکتر داشته باشد.
جستجو در حروف الفبا
را match
تابع را می توان برای یافتن هر حروف الفبای درون یک رشته استفاده کرد. بیایید متغیر متن را با متن زیر مقداردهی اولیه کنیم:
text = "The film Titanic was released in 1998"
اکنون برای یافتن تمام حروف الفبا، چه بزرگ و چه کوچک، می توانیم از عبارت regex زیر استفاده کنیم:
result = re.match(r"(a-zA-z)+", text)
این عبارت regex بیان می کند که با رشته متن برای هر حروف کوچکی مطابقت دارد a
به کوچک z
یا سرمایه A
به سرمایه Z
. علامت مثبت مشخص می کند که رشته باید حداقل یک کاراکتر داشته باشد. اجازه دهید print مطابقت یافت شده توسط عبارت بالا:
print(result.group(0))
خروجی:
The
در خروجی می بینید که کلمه اول ie The
برگردانده می شود. این به این دلیل است که match
تابع فقط اولین تطابق یافت شده را برمی گرداند. در regex مشخص کردیم که الگوها را با الفبای کوچک و بزرگ پیدا کنید a
به z
. اولین مسابقه یافت شده بود The
. بعد از کلمه The
یک فاصله وجود دارد که به عنوان یک حرف الفبا در نظر گرفته نمی شود، بنابراین تطبیق متوقف شد و عبارت فقط برگردانده شد The
، که اولین مسابقه است.
با این حال، یک مشکل در این مورد وجود دارد. اگر رشته ای به جای الفبا با عدد شروع شود، match
حتی اگر حروف بعد از عدد وجود داشته باشد، تابع صفر خواهد شد. بیایید این را در عمل ببینیم:
text = "1998 was the year when the film titanic was released"
result = re.match(r"(a-zA-z)+", text)
type(result)
خروجی:
NoneType
در اسکریپت بالا متغیر متن را به روز کرده ایم و اکنون با یک رقم شروع می شود. ما سپس استفاده کردیم match
عملکرد جستجوی حروف الفبا در رشته. اگرچه رشته متن حاوی حروف الفبا است، از آن زمان null برگردانده می شود match
تابع فقط با اولین عنصر در رشته مطابقت دارد.
برای حل این مشکل می توانیم از search
تابع.
تابع جستجو
را search
تابع مشابه است match
تابع یعنی سعی می کند با الگوی مشخص شده مطابقت داشته باشد. با این حال، بر خلاف match
تابع، به جای تطبیق تنها با عنصر اول، الگو را در سطح جهانی مطابقت می دهد. بنابراین، search
تابع یک تطابق را برمی گرداند حتی اگر رشته حاوی الفبای ابتدای رشته نباشد اما در جای دیگری از رشته دارای الفبا باشد، همانطور که در زیر نشان داده شده است:
text = "1998 was the year when the film titanic was released"
result = re.search(r"(a-zA-z)+", text)
print(result.group(0))
خروجی:
was
را search
تابع “بود” را برمی گرداند زیرا این اولین تطابق است که در رشته متن یافت می شود.
رشته تطبیق از ابتدا
برای بررسی اینکه آیا یک رشته با یک کلمه خاص شروع می شود، می توانید از کلید هویج استفاده کنید ^
به دنبال آن کلمه مطابقت با search
مطابق شکل زیر عمل کنید. فرض کنید رشته زیر را داریم:
text = "XYZ 1998 was the year when the film titanic was released"
اگر بخواهیم بفهمیم که آیا رشته با “1998” شروع می شود، می توانیم از آن استفاده کنیم search
عملکرد به شرح زیر است:
result = re.search(r"^1998", text)
type(result)
در خروجی، null
از آنجایی که رشته متنی در ابتدا حاوی “1998” نیست، بازگردانده خواهد شد.
حالا بیایید متغیر متن محتوا را تغییر دهیم و “1998” را در ابتدا اضافه کنیم و سپس بررسی کنیم که آیا “1998” در ابتدا پیدا شده است یا خیر. اسکریپت زیر را اجرا کنید:
text = "1998 was the year when the film titanic was released"
if re.search(r"^1998", text):
print("Match found")
else:
print("Match not found")
خروجی:
Match found
تطبیق رشته ها از انتها
برای بررسی اینکه آیا یک رشته به پایان می رسد با یک کلمه خاص یا نه، می توانیم از کلمه در عبارت منظم و به دنبال آن علامت دلار استفاده کنیم. علامت دلار پایان بیانیه را نشان می دهد. به مثال زیر دقت کنید:
text = "1998 was the year when the film titanic was released"
if re.search(r"1998$", text):
print("Match found")
else:
print("Match not found")
در اسکریپت بالا سعی کردیم بفهمیم که آیا رشته متن با “1998” ختم می شود یا خیر، که اینطور نیست.
خروجی:
Match not found
حال اگر رشته را بهروزرسانی کنیم و «1998» را در انتهای رشته متن اضافه کنیم، اسکریپت فوق مطابق شکل زیر «Match found» را برمیگرداند:
text = "was the year when the film titanic was released 1998"
if re.search(r"1998$", text):
print("Match found")
else:
print("Match not found")
خروجی:
Match found
جایگزینی متن در یک رشته
تا به حال ما از regex برای یافتن اینکه آیا یک الگو در یک رشته وجود دارد یا خیر استفاده کرده ایم. بیایید با یک تابع regex پیشرفته دیگر به جلو حرکت کنیم، یعنی جایگزین کردن متن در یک رشته. را sub
تابع برای این منظور استفاده می شود.
بیایید یک مثال ساده از تابع جایگزین بیاوریم. فرض کنید رشته زیر را داریم:
text = "The film Pulp Fiction was released in year 1994"
برای جایگزینی رشته “Pulp Fiction” با “Forrest Gump” (فیلم دیگری که در سال 1994 منتشر شد) می توانیم از sub
عملکرد به شرح زیر است:
result = re.sub(r"Pulp Fiction", "Forrest Gump", text)
اولین پارامتر به sub
تابع عبارت منظمی است که الگو را برای جایگزینی پیدا می کند. پارامتر دوم متن جدیدی است که می خواهید به عنوان جایگزینی برای متن قدیمی و پارامتر سوم رشته متن است. روی که عملیات جایگزین انجام خواهد شد.
اگر شما print متغیر نتیجه، رشته جدید را خواهید دید.
حالا بیایید تمام حروف الفبای رشته خود را با کاراکتر “X” جایگزین کنیم. اسکریپت زیر را اجرا کنید:
text = "The film Pulp Fiction was released in year 1994"
result = re.sub(r"(a-z)", "X", text)
print(result)
خروجی:
TXX XXXX PXXX FXXXXXX XXX XXXXXXXX XX XXXX 1994
از خروجی می توان فهمید که همه کاراکترها به جز بزرگ ها جایگزین شده اند. این به این دلیل است که ما مشخص کردیم a-z
فقط و نه A-Z
. دو راه برای حل این مشکل وجود دارد. شما هم می توانید مشخص کنید A-Z
در عبارت منظم همراه با a-z
به شرح زیر است:
result = re.sub(r"(a-zA-Z)", "X", text)
یا می توانید پارامتر اضافی را ارسال کنید flags
به تابع sub و مقدار آن را بر روی re.I
که به حروف بزرگ و کوچک اشاره دارد، به شرح زیر:
result = re.sub(r"(a-z)", "X", text, flags=re.I)
جزئیات بیشتر در مورد انواع مختلف پرچم ها را می توانید در Python regex پیدا کنید اسناد رسمی page.
کلاس های کاراکتر کوتاه نویسی
انواع مختلفی از کلاسهای کاراکتر کوتاهنویسی وجود دارد که میتوان از آنها برای انجام انواع مختلف توابع دستکاری رشتهها بدون نیاز به نوشتن منطق پیچیده استفاده کرد. در این بخش به برخی از آنها می پردازیم:
حذف ارقام از یک رشته
عبارت regex برای یافتن ارقام در یک رشته است \d
. از این الگو می توان برای حذف ارقام از یک رشته با جایگزین کردن آنها با یک رشته خالی به طول صفر مانند شکل زیر استفاده کرد:
text = "The film Pulp Fiction was released in year 1994"
result = re.sub(r"\d", "", text)
print(result)
خروجی:
The film Pulp Fiction was released in year
حذف حروف الفبا از رشته
text = "The film Pulp Fiction was released in year 1994"
result = re.sub(r"(a-z)", "", text, flags=re.I)
print(result)
خروجی:
1994
حذف کاراکترهای کلمه
اگر می خواهید تمام کاراکترهای کلمه (حروف و اعداد) را از یک رشته حذف کنید و کاراکترهای باقی مانده را حفظ کنید، می توانید از \w
الگو را در regex خود قرار دهید و آن را با یک رشته خالی به طول صفر جایگزین کنید، همانطور که در زیر نشان داده شده است:
text = "The film, '@Pulp Fiction' was ? released in % $ year 1994."
result = re.sub(r"\w","", text, flags = re.I)
print(result)
خروجی:
, '@ ' ? % $ .
خروجی نشان می دهد که تمام اعداد و حروف الفبا حذف شده اند.
حذف کاراکترهای غیر کلمه ای
برای حذف تمام کاراکترهای غیر کلمه، \W
الگو را می توان به صورت زیر استفاده کرد:
text = "The film, '@Pulp Fiction' was ? released in % $ year 1994."
result = re.sub(r"\W", "", text, flags=re.I)
print(result)
خروجی:
ThefilmPulpFictionwasreleasedinyear1994
از خروجی می بینید که همه چیز حذف شده است (حتی فاصله ها) به جز اعداد و حروف الفبا.
گروه بندی الگوهای چندگانه
می توانید الگوهای متعددی را برای مطابقت یا جایگزینی در یک رشته با استفاده از براکت مربع گروه بندی کنید. در واقع ما این کار را زمانی انجام دادیم که حروف بزرگ و کوچک را با هم تطبیق دادیم. بیایید چندین علامت نگارشی را گروه بندی کنیم و آنها را از یک رشته حذف کنیم:
text = "The film, '@Pulp Fiction' was ? released _ in % $ year 1994."
result = re.sub(r"(,@\'?\.$%_)", "", text, flags=re.I)
print(result)
خروجی:
The film Pulp Fiction was released in year 1994
می بینید که رشته در متغیر متن دارای چندین علامت نگارشی است، ما همه این علائم نگارشی را در عبارت regex با استفاده از براکت مربع گروه بندی کردیم. ذکر این نکته ضروری است که با یک نقطه و یک نقل قول باید از دنباله فرار یعنی اسلش به عقب استفاده کنیم. این به این دلیل است که به طور پیش فرض عملگر نقطه برای هر کاراکتری استفاده می شود و از تک نقل قول برای نشان دادن یک رشته استفاده می شود.
حذف فاصله های متعدد
گاهی اوقات در نتیجه حذف کلمات یا علائم نگارشی، فاصله های متعددی بین کلمات ظاهر می شود. به عنوان مثال، در خروجی آخرین مثال، فاصله های متعددی بین آنها وجود دارد in
و year
. این فضاها را می توان با استفاده از \s
الگو، که به یک فضای واحد اشاره دارد.
text = "The film Pulp Fiction was released in year 1994."
result = re.sub(r"\s+"," ", text, flags = re.I)
print(result)
خروجی:
The film Pulp Fiction was released in year 1994.
در اسکریپت بالا از عبارت استفاده کردیم \s+
که به فضاهای منفرد یا چندگانه اشاره دارد.
حذف Spaces از شروع و پایان
گاهی اوقات جمله ای داریم که با فاصله شروع یا به پایان می رسد که اغلب مطلوب نیست. اسکریپت زیر فاصله های ابتدای جمله را حذف می کند:
text = " The film Pulp Fiction was released in year 1994"
result = re.sub(r"^\s+", "", text)
print(result)
خروجی:
The film Pulp Fiction was released in year 1994
به طور مشابه، برای حذف فضای انتهای رشته، می توان از اسکریپت زیر استفاده کرد:
text = "The film Pulp Fiction was released in year 1994 "
result = re.sub(r"\s+$", "", text)
print(result)
حذف یک کاراکتر
گاهی اوقات حذف علائم نگارشی، مانند آپستروف، منجر به یک کاراکتر می شود که معنایی ندارد. به عنوان مثال، اگر آپستروف را از کلمه حذف کنید Jacob's
و آن را با فاصله جایگزین کنید، رشته حاصل است Jacob s
. اینجا s
معنی ندارد. چنین کاراکترهای منفرد را می توان با استفاده از regex همانطور که در زیر نشان داده شده است حذف کرد:
text = "The film Pulp Fiction s was b released in year 1994"
result = re.sub(r"\s+(a-zA-Z)\s+", " ", text)
print(result)
خروجی:
The film Pulp Fiction was released in year 1994
اسکریپت هر حرف کوچک یا بزرگ بین یک یا چند فاصله را با یک فاصله جایگزین میکند.
تقسیم یک رشته
تقسیم رشته یکی دیگر از عملکردهای بسیار مهم است. رشته ها را می توان با استفاده از تقسیم کرد split
عملکرد از بسته re. را split
تابع لیستی از نشانه های تقسیم شده را برمی گرداند. بیایید یک رشته از کلمات را در جایی که یک یا چند کاراکتر فاصله پیدا می شود، تقسیم کنیم، همانطور که در زیر نشان داده شده است:
text = "The film Pulp Fiction was released in year 1994 "
result = re.split(r"\s+", text)
print(result)
خروجی:
('The', 'film', 'Pulp', 'Fiction', 'was', 'released', 'in', 'year', '1994', '')
به طور مشابه، می توانید از دیگر عبارات regex برای تقسیم یک رشته با استفاده از عبارت استفاده کنید split
کارکرد. به عنوان مثال، موارد زیر split
تابع وقتی یک کاما پیدا می شود رشته کلمات را تقسیم می کند:
text = "The film, Pulp Fiction, was released in year 1994"
result = re.split(r"\,", text)
print(result)
خروجی:
('The film', ' Pulp Fiction', ' was released in year 1994')
یافتن همه موارد
را match
تابع یک مسابقه را انجام می دهد روی اولین عنصر در حالی که search
تابع یک جستجوی جهانی انجام می دهد روی رشته و اولین نمونه مطابق را برمی گرداند.
به عنوان مثال، اگر رشته زیر را داشته باشیم:
text = "I want to buy a mobile between 200 and 400 euros"
ما می خواهیم تمام ارقام این رشته را جستجو کنیم. اگر از search
تابع، فقط اولین رخداد ارقام یعنی 200 مطابق شکل زیر برگردانده می شود:
result = re.search(r"\d+", text)
print(result.group(0))
خروجی:
200
از سوی دیگر، findall
تابع لیستی را برمیگرداند که شامل تمام عبارات منطبق مانند شکل زیر است:
text = "I want to buy a mobile between 200 and 400 euros"
result = re.findall(r"\d+", text)
print(result)
خروجی:
('200', '400')
شما می توانید از خروجی ببینید که هر دو “200” و “400” توسط findall
تابع.
نتیجه
در این مقاله به بررسی برخی از متداولترین توابع regex در پایتون پرداختیم. عبارات منظم برای پیش پردازش متن بسیار مفید هستند که می توانند بیشتر برای برنامه های مختلف استفاده شوند، مانند مدل سازی موضوع، طبقه بندی متن، تحلیل احساسات، و خلاصه سازی متن، و غیره.
(برچسبها به ترجمه)# python
منتشر شده در 1403-01-27 13:52:07