পাইথন রেগুলার এক্সপ্রেশন

রেগুলার এক্সপ্রেশন হল টেক্সট প্যাটার্ন মেলানোর জন্য একটি শক্তিশালী ভাষা। এই পৃষ্ঠাটি আমাদের পাইথন অনুশীলনের জন্য যথেষ্ট নিয়মিত এক্সপ্রেশনগুলির একটি প্রাথমিক ভূমিকা দেয় এবং পাইথনে রেগুলার এক্সপ্রেশনগুলি কীভাবে কাজ করে তা দেখায়। Python "re" মডিউল নিয়মিত এক্সপ্রেশন সমর্থন প্রদান করে।

পাইথনে একটি নিয়মিত অভিব্যক্তি অনুসন্ধান সাধারণত লেখা হয়:

match = re.search(pat, str)

re.search() পদ্ধতি একটি রেগুলার এক্সপ্রেশন প্যাটার্ন এবং একটি স্ট্রিং নেয় এবং স্ট্রিংয়ের মধ্যে সেই প্যাটার্নের জন্য অনুসন্ধান করে। যদি অনুসন্ধান সফল হয়, অনুসন্ধান() একটি মিল বস্তু প্রদান করে বা অন্যথায় কিছুই নয়। অতএব, অনুসন্ধানটি সফল হয়েছে কিনা তা পরীক্ষা করার জন্য সাধারণত একটি যদি-বিবৃতি দ্বারা অনুসন্ধানটি অনুসরণ করা হয়, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে যা প্যাটার্ন 'শব্দ:' অনুসন্ধান করে একটি 3 অক্ষরের শব্দ (নিচে বিস্তারিত):

import re

str = 'an example word:cat!!'
match = re.search(r'word:\w\w\w', str)
# If-statement after search() tests if it succeeded
if match:
  print('found', match.group()) ## 'found word:cat'
else:
  print('did not find')

কোড match = re.search(pat, str) সার্চের ফলাফলকে "match" নামের একটি ভেরিয়েবলে সংরক্ষণ করে। তারপর যদি-বিবৃতি ম্যাচ পরীক্ষা করে -- যদি সত্য অনুসন্ধান সফল হয় এবং match.group() হল মিলিত পাঠ্য (যেমন 'word:cat')। অন্যথায় যদি মিলটি মিথ্যা হয় (আরো নির্দিষ্ট করার জন্য কিছুই নয়), তাহলে অনুসন্ধানটি সফল হয়নি এবং কোন মিলিত পাঠ্য নেই।

প্যাটার্ন স্ট্রিংয়ের শুরুতে 'r' একটি পাইথন "কাঁচা" স্ট্রিংকে চিহ্নিত করে যা ব্যাকস্ল্যাশের মধ্য দিয়ে যায় পরিবর্তন ছাড়াই যা রেগুলার এক্সপ্রেশনের জন্য খুবই সহজ (জাভা এই বৈশিষ্ট্যটি খারাপভাবে প্রয়োজন!)। আমি সুপারিশ করি যে আপনি সবসময় একটি অভ্যাস হিসাবে 'r' দিয়ে প্যাটার্ন স্ট্রিং লিখুন।

মৌলিক নিদর্শন

রেগুলার এক্সপ্রেশনের ক্ষমতা হল তারা প্যাটার্ন নির্দিষ্ট করতে পারে, শুধু নির্দিষ্ট অক্ষর নয়। এখানে সবচেয়ে মৌলিক নিদর্শন রয়েছে যা একক অক্ষরের সাথে মেলে:

  • a, X, 9, < -- সাধারন অক্ষরগুলো ঠিক নিজেদের সাথে মিলে যায়। যে মেটা-অক্ষরগুলি নিজেদের সাথে মেলে না কারণ তাদের বিশেষ অর্থ রয়েছে: . ^ $ * +? { [ ] \ | ( ) (নিচে বিস্তারিত)
  • . (একটি পিরিয়ড) -- নতুন লাইন '\n' ছাড়া যেকোনো একক অক্ষরের সাথে মেলে
  • \w -- (ছোট হাতের w) একটি "শব্দ" অক্ষরের সাথে মেলে: একটি অক্ষর বা অঙ্ক বা আন্ডারবার [a-zA-Z0-9_]। উল্লেখ্য যে যদিও "শব্দ" এর জন্য মেমোনিক, এটি শুধুমাত্র একটি একক শব্দ চারের সাথে মেলে, একটি সম্পূর্ণ শব্দ নয়। \W (বড় হাতের W) যেকোন অ-শব্দ অক্ষরের সাথে মেলে।
  • \b -- শব্দ এবং অ-শব্দের মধ্যে সীমানা
  • \s -- (ছোট হাতের গুলি) একটি একক হোয়াইটস্পেস অক্ষরের সাথে মেলে -- স্পেস, নিউলাইন, রিটার্ন, ট্যাব, ফর্ম [ \n\r\t\f]। \S (বড় হাতের S) যেকোনো নন-হোয়াইটস্পেস অক্ষরের সাথে মেলে।
  • \t, \n, \r -- ট্যাব, নতুন লাইন, রিটার্ন
  • \d -- দশমিক সংখ্যা [0-9] (কিছু পুরানো রেজেক্স ইউটিলিটিগুলি \d সমর্থন করে না, তবে তারা সবগুলি \w এবং \s সমর্থন করে)
  • ^ = শুরু, $ = শেষ -- স্ট্রিংয়ের শুরু বা শেষের সাথে মেলে
  • \ -- একটি চরিত্রের "বিশেষত্ব" বাধা দেয়। সুতরাং, উদাহরণস্বরূপ, ব্যবহার করুন \. একটি পিরিয়ড বা \\ একটি স্ল্যাশ মেলাতে। যদি আপনি নিশ্চিত না হন যে একটি অক্ষরের বিশেষ অর্থ আছে, যেমন '@', তাহলে আপনি এটির সামনে একটি স্ল্যাশ রাখার চেষ্টা করতে পারেন, \@৷ যদি এটি একটি বৈধ পালানোর ক্রম না হয়, যেমন \c, আপনার পাইথন প্রোগ্রাম একটি ত্রুটির সাথে থামবে।

মৌলিক উদাহরণ

কৌতুক: তিন চোখ বিশিষ্ট শূকরকে কি বলে? piiig!

একটি স্ট্রিংয়ের মধ্যে একটি প্যাটার্নের জন্য নিয়মিত অভিব্যক্তি অনুসন্ধানের প্রাথমিক নিয়মগুলি হল:

  • অনুসন্ধানটি শুরু থেকে শেষ পর্যন্ত স্ট্রিং দিয়ে এগিয়ে যায়, প্রথম মিল পাওয়ায় থামে
  • সমস্ত প্যাটার্ন অবশ্যই মিলিত হতে হবে, তবে সমস্ত স্ট্রিং নয়৷
  • match = re.search(pat, str) সফল হলে, ম্যাচটি কোনটি নয় এবং বিশেষ করে match.group() হল মেলে লেখা পাঠ্য
  ## Search for pattern 'iii' in string 'piiig'.
  ## All of the pattern must match, but it may appear anywhere.
  ## On success, match.group() is matched text.
  match = re.search(r'iii', 'piiig') # found, match.group() == "iii"
  match = re.search(r'igs', 'piiig') # not found, match == None

  ## . = any char but \n
  match = re.search(r'..g', 'piiig') # found, match.group() == "iig"

  ## \d = digit char, \w = word char
  match = re.search(r'\d\d\d', 'p123g') # found, match.group() == "123"
  match = re.search(r'\w\w\w', '@@abcd!!') # found, match.group() == "abc"

পুনরাবৃত্তি

আপনি যখন প্যাটার্নে পুনরাবৃত্তি নির্দিষ্ট করতে + এবং * ব্যবহার করেন তখন জিনিসগুলি আরও আকর্ষণীয় হয়ে ওঠে

  • + -- এর বাম দিকে প্যাটার্নের 1 বা তার বেশি ঘটনা, যেমন 'i+' = এক বা একাধিক i's
  • * -- এর বাম দিকে প্যাটার্নের 0 বা তার বেশি ঘটনা
  • ? -- প্যাটার্নের বাম দিকে 0 বা 1 ঘটনা মেলে

বাম এবং সবচেয়ে বড়

প্রথমে অনুসন্ধানটি প্যাটার্নের জন্য সবচেয়ে বামদিকের মিল খুঁজে পায়, এবং দ্বিতীয়ত এটি যতটা সম্ভব স্ট্রিং ব্যবহার করার চেষ্টা করে -- অর্থাৎ + এবং * যতদূর সম্ভব যান (+ এবং *কে "লোভী" বলা হয়)।

পুনরাবৃত্তি উদাহরণ

  ## i+ = one or more i's, as many as possible.
  match = re.search(r'pi+', 'piiig') # found, match.group() == "piii"

  ## Finds the first/leftmost solution, and within it drives the +
  ## as far as possible (aka 'leftmost and largest').
  ## In this example, note that it does not get to the second set of i's.
  match = re.search(r'i+', 'piigiiii') # found, match.group() == "ii"

  ## \s* = zero or more whitespace chars
  ## Here look for 3 digits, possibly separated by whitespace.
  match = re.search(r'\d\s*\d\s*\d', 'xx1 2   3xx') # found, match.group() == "1 2   3"
  match = re.search(r'\d\s*\d\s*\d', 'xx12  3xx') # found, match.group() == "12  3"
  match = re.search(r'\d\s*\d\s*\d', 'xx123xx') # found, match.group() == "123"

  ## ^ = matches the start of string, so this fails:
  match = re.search(r'^b\w+', 'foobar') # not found, match == None
  ## but without the ^ it succeeds:
  match = re.search(r'b\w+', 'foobar') # found, match.group() == "bar"

ইমেল উদাহরণ

ধরুন আপনি 'xyz alice-b@google.com বেগুনি বানর' স্ট্রিং এর ভিতরে ইমেল ঠিকানাটি খুঁজে পেতে চান। আমরা এটিকে একটি চলমান উদাহরণ হিসাবে ব্যবহার করব যাতে আরো রেগুলার এক্সপ্রেশন বৈশিষ্ট্য প্রদর্শন করা যায়। এখানে প্যাটার্ন r'\w+@\w+' ব্যবহার করে একটি প্রচেষ্টা:

  str = 'purple alice-b@google.com monkey dishwasher'
  match = re.search(r'\w+@\w+', str)
  if match:
    print(match.group())  ## 'b@google'

অনুসন্ধানটি এই ক্ষেত্রে সম্পূর্ণ ইমেল ঠিকানা পায় না কারণ \w '-' বা 'এর সাথে মেলে না। ঠিকানায় আমরা নীচের রেগুলার এক্সপ্রেশন বৈশিষ্ট্যগুলি ব্যবহার করে এটি ঠিক করব৷

চতুস্কন বন্ধনী

বর্গাকার বন্ধনীগুলি অক্ষরের একটি সেট নির্দেশ করতে ব্যবহার করা যেতে পারে, তাই [abc] 'a' বা 'b' বা 'c' এর সাথে মেলে। কোড \w, \s ইত্যাদি বর্গাকার বন্ধনীর মধ্যেও কাজ করে একটি ব্যতিক্রম যে ডট (.) মানে শুধু একটি আক্ষরিক বিন্দু। ইমেল সমস্যার জন্য, বর্গাকার বন্ধনী হল 'যোগ করার একটি সহজ উপায়।' এবং '-' অক্ষরের সেটে যা @ এর চারপাশে r'[\w.-]+@[\w.-]+' প্যাটার্ন সহ প্রদর্শিত হতে পারে পুরো ইমেল ঠিকানা পেতে:

  match = re.search(r'[\w.-]+@[\w.-]+', str)
  if match:
    print(match.group())  ## 'alice-b@google.com'
(আরো বর্গাকার-বন্ধনী বৈশিষ্ট্য) আপনি একটি ব্যাপ্তি নির্দেশ করতে একটি ড্যাশও ব্যবহার করতে পারেন, তাই [az] সমস্ত ছোট হাতের অক্ষরের সাথে মেলে। একটি ব্যাপ্তি নির্দেশ না করে একটি ড্যাশ ব্যবহার করতে, ড্যাশটি সবশেষে রাখুন, যেমন [abc-]। একটি বর্গাকার-বন্ধনী সেটের শুরুতে একটি আপ-হ্যাট (^) এটিকে উল্টে দেয়, তাই [^ab] মানে 'a' বা 'b' ছাড়া যেকোনো অক্ষর।

গ্রুপ নিষ্কাশন

একটি রেগুলার এক্সপ্রেশনের "গ্রুপ" ফিচার আপনাকে মিলিত টেক্সটের কিছু অংশ বাছাই করতে দেয়। ধরুন ইমেইল সমস্যার জন্য আমরা আলাদাভাবে ইউজারনেম এবং হোস্ট এক্সট্রাক্ট করতে চাই। এটি করার জন্য, প্যাটার্নে ব্যবহারকারীর নাম এবং হোস্টের চারপাশে বন্ধনী ( ) যুক্ত করুন, এইভাবে: r'([\w.-]+)@([\w.-]+)'। এই ক্ষেত্রে, প্যাটার্নটি কী মিলবে তা বন্ধনীগুলি পরিবর্তন করে না, পরিবর্তে তারা মিল পাঠ্যের ভিতরে যৌক্তিক "গোষ্ঠী" স্থাপন করে। একটি সফল অনুসন্ধানে, match.group(1) হল ১ম বাম বন্ধনীর সাথে মিলিত পাঠ্য এবং match.group(2) হল ২য় বাম বন্ধনীর সাথে সম্পর্কিত পাঠ্য। প্লেইন match.group() এখনও যথারীতি পুরো ম্যাচ টেক্সট।

  str = 'purple alice-b@google.com monkey dishwasher'
  match = re.search(r'([\w.-]+)@([\w.-]+)', str)
  if match:
    print(match.group())   ## 'alice-b@google.com' (the whole match)
    print(match.group(1))  ## 'alice-b' (the username, group 1)
    print(match.group(2))  ## 'google.com' (the host, group 2)

রেগুলার এক্সপ্রেশনের সাথে একটি সাধারণ ওয়ার্কফ্লো হল যে আপনি যে জিনিসটি খুঁজছেন তার জন্য আপনি একটি প্যাটার্ন লেখেন, আপনি যে অংশগুলি চান তা বের করতে বন্ধনীর গোষ্ঠী যোগ করুন।

findall

findall() সম্ভবত re মডিউলের একক সবচেয়ে শক্তিশালী ফাংশন। উপরে আমরা একটি প্যাটার্নের জন্য প্রথম মিল খুঁজে পেতে re.search() ব্যবহার করেছি। findall() *সমস্ত* মিলগুলি খুঁজে পায় এবং স্ট্রিংগুলির একটি তালিকা হিসাবে সেগুলিকে ফেরত দেয়, প্রতিটি স্ট্রিং একটি ম্যাচের প্রতিনিধিত্ব করে।
  ## Suppose we have a text with many email addresses
  str = 'purple alice@google.com, blah monkey bob@abc.com blah dishwasher'

  ## Here re.findall() returns a list of all the found email strings
  emails = re.findall(r'[\w\.-]+@[\w\.-]+', str) ## ['alice@google.com', 'bob@abc.com']
  for email in emails:
    # do something with each found email string
    print(email)

ফাইল সহ findall

ফাইলগুলির জন্য, আপনি ফাইলের লাইনগুলির উপর পুনরাবৃত্তি করার জন্য একটি লুপ লেখার অভ্যাস করতে পারেন এবং তারপর আপনি প্রতিটি লাইনে findall() কল করতে পারেন। পরিবর্তে, findall() কে আপনার জন্য পুনরাবৃত্তি করতে দিন -- অনেক ভালো! শুধু findall() এ পুরো ফাইলের পাঠ্যটি ফিড করুন এবং এটিকে একটি একক ধাপে সমস্ত মিলের একটি তালিকা ফেরত দিন (মনে রাখবেন যে f.read() একটি একক স্ট্রিংয়ে একটি ফাইলের পুরো পাঠ্য ফেরত দেয়):

  # Open file
  f = open('test.txt', encoding='utf-8')
  # Feed the file text into findall(); it returns a list of all the found strings
  strings = re.findall(r'some pattern', f.read())

Findall এবং Groups

বন্ধনী ( ) গ্রুপ প্রক্রিয়া findall() এর সাথে একত্রিত করা যেতে পারে। যদি প্যাটার্নে 2 বা তার বেশি বন্ধনী গোষ্ঠী অন্তর্ভুক্ত থাকে, তাহলে স্ট্রিংগুলির একটি তালিকা ফেরত দেওয়ার পরিবর্তে, findall() *tuples* এর একটি তালিকা প্রদান করে। প্রতিটি টিপল প্যাটার্নের একটি মিল উপস্থাপন করে, এবং টিপলের ভিতরে রয়েছে গ্রুপ(1), গ্রুপ(2) .. ডেটা। তাই যদি ইমেল প্যাটার্নে 2টি বন্ধনী গোষ্ঠী যুক্ত করা হয়, তাহলে findall() টিপলের একটি তালিকা প্রদান করে, প্রতিটি দৈর্ঘ্য 2 যাতে ব্যবহারকারীর নাম এবং হোস্ট থাকে, যেমন ('alice', 'google.com')।

  str = 'purple alice@google.com, blah monkey bob@abc.com blah dishwasher'
  tuples = re.findall(r'([\w\.-]+)@([\w\.-]+)', str)
  print(tuples)  ## [('alice', 'google.com'), ('bob', 'abc.com')]
  for tuple in tuples:
    print(tuple[0])  ## username
    print(tuple[1])  ## host

একবার আপনার কাছে টিপলের তালিকা হয়ে গেলে, আপনি প্রতিটি টিপলের জন্য কিছু গণনা করতে এটিকে লুপ করতে পারেন। যদি প্যাটার্নে কোন বন্ধনী অন্তর্ভুক্ত না থাকে, তাহলে findall() আগের উদাহরণের মতো পাওয়া স্ট্রিংগুলির একটি তালিকা প্রদান করে। প্যাটার্নে যদি বন্ধনীর একটি একক সেট অন্তর্ভুক্ত থাকে, তাহলে findall() সেই একক গোষ্ঠীর সাথে সম্পর্কিত স্ট্রিংগুলির একটি তালিকা প্রদান করে। (অস্পষ্ট ঐচ্ছিক বৈশিষ্ট্য: কখনও কখনও প্যাটার্নে আপনার প্যারেন ( ) গ্রুপিং থাকে, কিন্তু আপনি যা বের করতে চান না। সেক্ষেত্রে, শুরুতে a ?: দিয়ে প্যারেন লিখুন, যেমন (?: ) এবং সেই বাম প্যারেন হবে একটি গ্রুপ ফলাফল হিসাবে গণনা করা হয় না.)

RE ওয়ার্কফ্লো এবং ডিবাগ

রেগুলার এক্সপ্রেশন প্যাটার্নগুলি শুধুমাত্র কয়েকটি অক্ষরে অনেক অর্থ প্যাক করে, কিন্তু সেগুলি এত ঘন, আপনি আপনার প্যাটার্নগুলি ডিবাগ করতে অনেক সময় ব্যয় করতে পারেন৷ আপনার রানটাইম সেট আপ করুন যাতে আপনি একটি প্যাটার্ন চালাতে পারেন এবং এটি সহজেই যা মেলে তা মুদ্রণ করতে পারেন, উদাহরণস্বরূপ একটি ছোট পরীক্ষার পাঠ্যে এটি চালিয়ে এবং findall() এর ফলাফল প্রিন্ট করে। যদি প্যাটার্নের সাথে কিছু মেলে না, তাহলে প্যাটার্নটিকে দুর্বল করার চেষ্টা করুন, এর কিছু অংশ মুছে ফেলুন যাতে আপনি অনেকগুলি মিল পান। যখন এটি কিছুই মেলে না, তখন আপনি কোন অগ্রগতি করতে পারবেন না কারণ দেখার মতো কিছু নেই। একবার এটি খুব বেশি মেলে, তারপর আপনি যা চান তা আঘাত করার জন্য ক্রমবর্ধমানভাবে এটিকে শক্ত করার জন্য কাজ করতে পারেন।

অপশন

পুনরায় ফাংশনগুলি প্যাটার্ন ম্যাচের আচরণ পরিবর্তন করার জন্য বিকল্পগুলি গ্রহণ করে। বিকল্প পতাকা অনুসন্ধান() বা Findall() ইত্যাদিতে একটি অতিরিক্ত আর্গুমেন্ট হিসেবে যোগ করা হয়েছে, যেমন re.search(pat, str, re.IGNORECASE)।

  • IGNORECASE -- ম্যাচিংয়ের জন্য বড়/ছোট হাতের পার্থক্য উপেক্ষা করুন, তাই 'a' 'a' এবং 'A' উভয়ের সাথে মিলে যায়।
  • DOTALL -- ডট (.) কে নতুন লাইনের সাথে মেলে - সাধারণত এটি নিউলাইন ছাড়া অন্য কিছুর সাথে মেলে। এটি আপনাকে ট্রিপ করতে পারে -- আপনি মনে করেন .* সবকিছুর সাথে মিলে যায়, কিন্তু ডিফল্টরূপে এটি একটি লাইনের শেষ অতিক্রম করে না। মনে রাখবেন যে \s (হোয়াইটস্পেস) নতুন লাইন অন্তর্ভুক্ত করে, তাই আপনি যদি একটি নতুন লাইন অন্তর্ভুক্ত করতে পারে এমন একটি সাদা স্থানের সাথে মিল করতে চান তবে আপনি শুধুমাত্র \s* ব্যবহার করতে পারেন
  • মাল্টিলাইন -- অনেক লাইন দিয়ে তৈরি একটি স্ট্রিং-এর মধ্যে, প্রতিটি লাইনের শুরু এবং শেষের সাথে ^ এবং $কে মেলাতে অনুমতি দিন। সাধারণত ^/$ পুরো স্ট্রিংয়ের শুরু এবং শেষের সাথে মেলে।

লোভী বনাম অ-লোভী (ঐচ্ছিক)

এটি ঐচ্ছিক বিভাগ যা অনুশীলনের জন্য প্রয়োজনীয় নয় এমন একটি আরও উন্নত নিয়মিত অভিব্যক্তি কৌশল দেখায়।

ধরুন আপনার কাছে ট্যাগ সহ টেক্সট আছে: <b>foo</b> এবং <i> so on</i>

ধরুন আপনি '(<.*>)' প্যাটার্নের সাথে প্রতিটি ট্যাগ মেলানোর চেষ্টা করছেন -- এটি প্রথমে কী মেলে?

ফলাফলটি একটু আশ্চর্যজনক, কিন্তু .* এর লোভনীয় দিকটি এটিকে পুরো '<b>foo</b> এবং <i>অত্যাধিক</i>' একটি বড় ম্যাচ হিসাবে মেলে। সমস্যা হল যে .* প্রথমে থামার পরিবর্তে যতদূর সম্ভব যায় > (ওরফে এটি "লোভী")।

রেগুলার এক্সপ্রেশনের একটি এক্সটেনশন আছে যেখানে আপনি একটি যোগ করেন? শেষে, যেমন .*? অথবা .+?, তাদের পরিবর্তন করে অ-লোভী হতে। এখন যত তাড়াতাড়ি সম্ভব তারা থামে। সুতরাং প্যাটার্ন '(<.*?>)' প্রথম ম্যাচ হিসেবে শুধু '<b>' পাবে, এবং দ্বিতীয় ম্যাচ হিসেবে '</b>' পাবে, এবং এভাবে প্রতিটি <..> জোড়া পালাক্রমে পাবে। শৈলী সাধারণত আপনি একটি .* ব্যবহার করেন? অবিলম্বে কিছু কংক্রিট মার্কার (> এই ক্ষেত্রে) দ্বারা অনুসরণ করা যা .*? রান প্রসারিত করতে বাধ্য হয়।

দ্য *? এক্সটেনশনের উৎপত্তি পার্লে, এবং রেগুলার এক্সপ্রেশন যা পার্লের এক্সটেনশনগুলিকে অন্তর্ভুক্ত করে সেগুলি পার্ল সামঞ্জস্যপূর্ণ রেগুলার এক্সপ্রেশন - pcre নামে পরিচিত। পাইথন pcre সমর্থন অন্তর্ভুক্ত করে। অনেক কমান্ড লাইন ইউটিলস ইত্যাদির একটি পতাকা থাকে যেখানে তারা pcre প্যাটার্ন গ্রহণ করে।

"এক্স এ থামানো ছাড়া এই সমস্ত অক্ষরগুলির" এই ধারণাটি কোড করার জন্য একটি পুরানো কিন্তু ব্যাপকভাবে ব্যবহৃত কৌশলটি বর্গাকার-বন্ধনী শৈলী ব্যবহার করে। উপরের জন্য আপনি প্যাটার্নটি লিখতে পারেন, কিন্তু .* এর পরিবর্তে সমস্ত অক্ষর পেতে, [^>]* ব্যবহার করুন যা সমস্ত অক্ষরকে এড়িয়ে যায় যা > নয় (প্রধান ^ "উল্টায়" বর্গ বন্ধনী সেট, তাই এটি মেলে কোন চর বন্ধনীতে নেই)।

প্রতিস্থাপন (ঐচ্ছিক)

re.sub(pat, replacement, str) ফাংশন প্রদত্ত স্ট্রিং-এ প্যাটার্নের সমস্ত উদাহরণ অনুসন্ধান করে এবং তাদের প্রতিস্থাপন করে। প্রতিস্থাপনের স্ট্রিংটিতে '\1', '\2' অন্তর্ভুক্ত থাকতে পারে যা মূল মিলিত পাঠ্য থেকে গোষ্ঠী(1), গোষ্ঠী(2) এবং আরও অনেক কিছু থেকে পাঠ্যকে নির্দেশ করে।

এখানে একটি উদাহরণ যা সমস্ত ইমেল ঠিকানা অনুসন্ধান করে এবং ব্যবহারকারীকে (\1) রাখার জন্য সেগুলিকে পরিবর্তন করে কিন্তু হোস্ট হিসাবে yo-yo-dyne.com আছে৷

  str = 'purple alice@google.com, blah monkey bob@abc.com blah dishwasher'
  ## re.sub(pat, replacement, str) -- returns new string with all replacements,
  ## \1 is group(1), \2 group(2) in the replacement
  print(re.sub(r'([\w\.-]+)@([\w\.-]+)', r'\1@yo-yo-dyne.com', str))
  ## purple alice@yo-yo-dyne.com, blah monkey bob@yo-yo-dyne.com blah dishwasher

ব্যায়াম

নিয়মিত অভিব্যক্তি অনুশীলন করতে, শিশুর নাম অনুশীলন দেখুন।