re.findall ('(ab | cd)', স্ট্রিং) বনাম re.findall ('(ab | সিডি) +', স্ট্রিং)


18

পাইথন নিয়মিত প্রকাশে আমি এই একক সমস্যার মুখোমুখি হই। আপনি re.findall('(ab|cd)', string)এবং এর মধ্যে পার্থক্য সম্পর্কে নির্দেশ দিতে পারেন re.findall('(ab|cd)+', string)?

import re

string = 'abcdla'
result = re.findall('(ab|cd)', string)
result2 = re.findall('(ab|cd)+', string)
print(result)
print(result2)

আসল আউটপুট হল:

['ab', 'cd']
['cd']

আমি বিভ্রান্ত হয়ে পড়েছি কেন দ্বিতীয় ফলাফলটিও এতে থাকে না 'ab'?


re.findall ('(ab | cd)', স্ট্রিং) ['ab', 'cd'] re.findall ('(ab | cd) +', স্ট্রিং) পায় ['সিডি']
রক

উত্তর:


15

+একটি পুনরাবৃত্তি কোয়ান্টিফায়ার যা এক বা একাধিক বারের সাথে মেলে। রেজেক্সে (ab|cd)+, আপনি + ব্যবহার করে ক্যাপচার গ্রুপটি পুনরাবৃত্তি (ab|cd) করছেন। এটি কেবল সর্বশেষ পুনরাবৃত্তিটি ক্যাপচার করবে।

আপনি এই আচরণ সম্পর্কে নিম্নরূপ যুক্তি দিতে পারেন:

আপনার স্ট্রিংটি বলুন abcdlaএবং রেজেক্সটি হ'ল (ab|cd)+। রেজেক্স ইঞ্জিন 0 এবং 1 পজিশনের মধ্যে গ্রুপের জন্য একটি মিল খুঁজে পাবে abএবং ক্যাপচার গ্রুপটি থেকে বেরিয়ে যাবে। তারপরে এটি +কোয়ান্টিফায়ার দেখায় এবং তাই আবার গ্রুপটি ক্যাপচার করার চেষ্টা করে এবং cd2 এবং 3 পজিশনের মধ্যে ক্যাপচার করবে ।


আপনি যদি সমস্ত পুনরাবৃত্তি ক্যাপচার করতে চান তবে আপনার কোন মিল এবং এর পরিবর্তে পুনরাবৃত্তি গোষ্ঠীটি ক্যাপচার করা উচিত । আপনি ভেতরের গ্রুপ অ ক্যাপচারিং করতে পারেন হিসাবে আমরা ভেতরের গ্রুপ ম্যাচ যত্ন সম্পর্কে না দিয়ে যা ম্যাচ((ab|cd)+)abcdcd((?:ab|cd)+)abcd

https://www.regular-expressions.info/captureall.html

দস্তাবেজ থেকে,

ধরা যাক আপনি !abc!বা এর মতো কোনও ট্যাগের সাথে মিল রাখতে চান !123!। কেবল এই দুটিই সম্ভব এবং আপনি ক্যাপচার করতে চান abcবা 123কোন ট্যাগটি পেয়েছেন তা নির্ধারণ করতে চান। এটি যথেষ্ট সহজ: !(abc|123)!কৌশলটি করবে।

এখন আসুন বলে যে ট্যাগের একাধিক সিকোয়েন্স ধারণ করতে পারে abcএবং 123, মত !abc123!বা !123abcabc!। দ্রুত এবং সহজ সমাধান হ'ল !(abc|123)+!। এই নিয়মিত প্রকাশটি এই ট্যাগগুলির সাথে সত্যিই মিলবে। তবে ক্যাপচারিং গ্রুপে ট্যাগের লেবেল ক্যাপচার করার জন্য এটি আর আমাদের প্রয়োজনীয়তা পূরণ করে না। যখন এই রেজেক্সটি মেলে !abc123!, ক্যাপচারিং গ্রুপটি কেবল স্টোর করে 123। এটি যখন মেলে তখন এটি !123abcabc!কেবল সঞ্চয় করে abc


আপনি কেবলমাত্র শেষের পুনরাবৃত্তি ক্যাপচার করে এবং কোনও ক্যাপচার গ্রুপটি কী তা এই স্পষ্ট করে কিছু ডকের সাথে লিঙ্ক করতে পারেন?
গুলজার

1
@ গুলজার, উত্তর আপডেট করেছেন। আপনি এখানে ক্যাপচার গ্রুপগুলি সম্পর্কে পড়তে পারেন - নিয়মিত- এক্সপ্রেসন.ইন.ফো
শশাঙ্ক ভি

@ শশাঙ্ক, ধন্যবাদ, আপনার উত্তরটি আমার যা প্রয়োজন ঠিক তা-ই। আন্তরিক ধন্যবাদ
রক করুন

@ রক দয়া করে উত্তরটি যদি আপনার প্রশ্নের সমাধান করে তবে তা গ্রহণ করুন।
শশাঙ্ক ভি

বন্ধনীর সাহায্যে পুরো রেজেক্সকে ঘিরে কোনও দরকার নেই। শুধু '(?:ab|cd)+'কাজ করবে।
ডিউক্লিং

5

আমি জানি না যে এটি আরও জিনিস পরিষ্কার করবে কিনা, তবে আসুন আমরা একটি সহজ উপায়ে হুডের নীচে কী ঘটে যায় তা কল্পনা করার চেষ্টা করি, আমরা ম্যাচটি ব্যবহার করে কী ঘটে তা সংক্ষিপ্ত করতে যাচ্ছি

   # group(0) return the matched string the captured groups are returned in groups or you can access them
   # using group(1), group(2).......  in your case there is only one group, one group will capture only 
   # one part so when you do this
   string = 'abcdla'
   print(re.match('(ab|cd)', string).group(0))  # only 'ab' is matched and the group will capture 'ab'
   print(re.match('(ab|cd)+', string).group(0)) # this will match 'abcd'  the group will capture only this part 'cd' the last iteration

findallএকই সাথে স্ট্রিংটি মেলে এবং গ্রাস করে নেওয়া যাক এই REGEX এর সাথে কী ঘটেছিল তা কল্পনা করুন '(ab|cd)':

      'abcdabla' ---> 1:   match: 'ab' |  capture : ab  | left to process:  'cdabla'
      'cdabla'   ---> 2:   match: 'cd' |  capture : cd  | left to process:  'abla'
      'abla'     ---> 3:   match: 'ab' |  capture : ab  | left to process:  'la'
      'la'       ---> 4:   match: '' |  capture : None  | left to process:  ''

      --- final : result captured ['ab', 'cd', 'ab']  

এখন একই জিনিস '(ab|cd)+'

      'abcdabla' ---> 1:   match: 'abcdab' |  capture : 'ab'  | left to process:  'la'
      'la'       ---> 2:   match: '' |  capture : None  | left to process:  ''
      ---> final result :   ['ab']  

আমি আশা করি এটি কিছুটা সাফ করে দেয়।


0

সুতরাং, আমার জন্য বিভ্রান্তিকর অংশটি ছিল এটাই

যদি এক বা একাধিক গোষ্ঠীগুলি প্যাটার্নে উপস্থিত থাকে তবে গোষ্ঠীর একটি তালিকা ফেরত দিন;

ডক্স

সুতরাং এটি আপনাকে পূর্ণ ম্যাচ নয়, কেবল একটি ক্যাপচারের ম্যাচ ফিরিয়ে দিচ্ছে। আপনি যদি এই গোষ্ঠীটিকে ক্যাপচার না করে থাকেন তবে (re.findall('(?:ab|cd)+', string)এটি ["abcd"]আমার প্রাথমিকভাবে প্রত্যাশা মতো ফিরে আসবে


আপনি যা প্রত্যাশা করেছিলেন বা না তা নিশ্চিত নয়
রিয়াড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.