রেজেক্স প্যাটার্ন টু ম্যাচ, যখন বাদ… / এর মধ্যে বাদে


108

- এডিট - বর্তমান উত্তরের কয়েকটি দরকারী ধারণা রয়েছে তবে আমি আরও কিছু সম্পূর্ণ চাই যা আমি 100% বুঝতে এবং পুনরায় ব্যবহার করতে পারি; আমি একটি অনুগ্রহ সেট যে কেন। এছাড়াও যে ধারণাগুলি সর্বত্র কাজ করে সেগুলি আমার পক্ষে মানক সিন্টেক্সের চেয়ে ভাল\K

এই প্রশ্নটি কীভাবে কিছু পরিস্থিতিতে এস 1 এস 2 এস 3 ব্যতীত আমি কোনও প্যাটার্নটি মেলাতে পারি about আমি আমার অর্থ দেখানোর জন্য একটি নির্দিষ্ট উদাহরণ দিচ্ছি তবে একটি সাধারণ উত্তর পছন্দ করি যা আমি 100% বুঝতে পারি তাই আমি অন্যান্য পরিস্থিতিতেও এটি পুনরায় ব্যবহার করতে পারি।

উদাহরণ

আমি পাঁচটি সংখ্যার সাথে মিল ব্যবহার \b\d{5}\bকরতে চাই তবে তিনটি পরিস্থিতিতে এস 1 এস 2 এস 3 নয়:

s1: কোনও লাইনে নয় যা এই বাক্যটির মতো সময়কালের সাথে শেষ হয়।

s2: পেরেনের ভিতরে কোথাও নেই।

s3: কোনও ব্লকের ভিতরে নয় যা শুরু হয় if(এবং শেষ হয়//endif

আমি কীভাবে এস 1 এস 2 এস 3 এর যে কোনও একটি লুকে হেড এবং লুকবিহিন্ড সহ সমাধান করতে হবে, বিশেষত সি # লুকবিহিনে বা \Kপিএইচপিতে।

এই ক্ষেত্রে

S1 (?m)(?!\d+.*?\.$)\d+

সি # লুকবিহাইন্ড সহ এস 3 (?<!if\(\D*(?=\d+.*?//endif))\b\d+\b

এস 3 পিএইচপি। কে সহ (?:(?:if\(.*?//endif)\D*)*\K\d+

তবে শর্তগুলির মিশ্রণটি আমার মাথাটি বিস্ফোরিত করে। আরও খারাপ খবরটি হ'ল আমার অন্য সময় এস 4 এস 5 যুক্ত করতে হবে অন্য সময়ে।

সুসংবাদটি হ'ল, আমি পিএইচপি, সি #, পাইথন বা আমার প্রতিবেশীর ওয়াশিং মেশিনের মতো সর্বাধিক প্রচলিত ভাষা ব্যবহার করে ফাইলগুলি প্রসেস করি কিনা সে বিষয়ে আমার চিন্তা নেই। :) আমি পাইথন ও জাভাতে বেশ শিক্ষানবিশ কিন্তু এর সমাধান আছে কিনা তা জানতে আগ্রহী।

সুতরাং কেউ এখানে নমনীয় রেসিপি ভাবেন কিনা তা দেখতে আমি এখানে এসেছি।

ইঙ্গিতগুলি ঠিক আছে: আপনার আমাকে পুরো কোড দেওয়ার দরকার নেই। :)

ধন্যবাদ.


1
\Kকোনও বিশেষ পিএইচপি সিনট্যাক্স নয়। আপনি কী বলতে চান দয়া করে বিশদভাবে ব্যাখ্যা করুন। আপনি যদি আমাদের বলার লক্ষ্য রেখে থাকেন যে আপনার কোনও "জটিল" সমাধানের প্রয়োজন নেই তখন আপনাকে বলতে হবে যে আপনার জন্য কী জটিল এবং কেন।
হ্যাক্রে

@ হ্যাক্রে আপনার অর্থ হ'ল রুবি এখন এটি ব্যবহার করছে এবং এটি পার্লে শুরু হয়েছে?
হান্স শিন্ডলার

1
না, কারণ এটি পিসিআরই যা পিএইচপি নয় (না রুবি)। পার্ল বিভিন্ন তবে PCRE হয় লক্ষ্য পার্ল Regex সামঞ্জস্যপূর্ণ হতে হবে।
হ্যাক্রে

আপনার এস 2 এবং এস 3 প্রয়োজনীয়তাগুলি পরস্পরবিরোধী বলে মনে হচ্ছে। S2 যে বোঝা প্রথম বন্ধনী সবসময় মেলানো হয় এবং নেস্টেড হতে পারে, কিন্তু S3 প্রয়োজন যে: "if("খোলা paren, বন্ধ করে দেওয়া একটি নয় ")", বরং একটি সঙ্গে "//endif"? এবং যদি এস 3 এর জন্য আপনি সত্যিই বোঝাতে চেয়েছিলেন যে যদি "//endif)"এই আইফটিটি ক্লজটি দিয়ে বন্ধ করা উচিত: তবে এস 3 প্রয়োজনীয়তাটি এস 2 এর একটি উপসেট।
রডগারুনার

@ হ্যাক্রে হ্যাঁ আমি পিসিআরই জানি তবে ব্যাখ্যা করার জন্য, প্রশ্নটি প্রোগ্রামিংয়ের ভাষা সম্পর্কে ... এটি বলে especially in C# lookbehind or \K in PHP... তবে সি # বর্ণনাকালীন কেবল সি # এটি নয় ET রুবি ওনিগুরামও খুব খারাপ নয় ... পিসিআরই ব্যবহার করে এমন অন্য কোন ভাষা আছে কি? নোটপ্যাড ++ বা সার্ভার সরঞ্জামগুলির বিষয়ে কথা না বলাই এটি ভাষার বৈশিষ্ট্যটি ব্যবহার করার বিষয়ে প্রশ্ন আমি আশা করি ব্যাখ্যাটি ব্যাখ্যা করা হয়েছে এবং ভুল মনে হলে দুঃখিত
হান্স শিন্ডলার

উত্তর:


205

হ্যান্স, আমি আমার পূর্বের উত্তরটি টোপ এবং গোশত গ্রহণ করব। আপনি বলেছিলেন যে আপনি "আরও কিছু সম্পূর্ণ" চান তাই আমি আশা করি আপনি দীর্ঘ উত্তরটি আপত্তি করবেন না - কেবল খুশি করার চেষ্টা করছেন। কিছু পটভূমি দিয়ে শুরু করা যাক।

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

আশ্চর্য

আশ্চর্যের বিষয় হল, কমপক্ষে একটি দক্ষ সমাধান রয়েছে যা সাধারণ, কার্যকর করা সহজ এবং বজায় রাখার জন্য একটি আনন্দ। এটি সমস্ত রেইগেক্স স্বাদের সাথে কাজ করে যা আপনাকে আপনার কোডে ক্যাপচার গ্রুপগুলি পরীক্ষা করতে দেয়। এবং এটি বেশ কয়েকটি সাধারণ প্রশ্নের উত্তর দিতে পারে যা প্রথমে আপনার থেকে পৃথক হতে পারে: "ডোনটস বাদে সমস্ত কিছু মেলে", "সমস্ত প্রতিস্থাপন করুন ...", "আমার মায়ের কালো তালিকায় থাকা সমস্ত শব্দগুলি মিলে", "উপেক্ষা করুন" ট্যাগগুলি "," তাপমাত্রার সাথে তাল মিলানো না থাকলে "...

দুঃখজনকভাবে, কৌশলটি ভালভাবে জানা যায়নি: আমার ধারণা, বিশটি যে প্রশ্নগুলি এটি ব্যবহার করতে পারে, কেবল তার একটিরই উত্তর রয়েছে যার মধ্যে এটি উল্লেখ করা হয়েছে - যার অর্থ পঞ্চাশ বা ষাট উত্তরের মধ্যে একটি হতে পারে। মন্তব্যে কোবির সাথে আমার বিনিময় দেখুন। কৌশলটি এই নিবন্ধটির কিছু গভীরতায় বর্ণিত হয়েছে যা এটিকে (আশাবাদী) "এখনকার সেরা রেজেক্স ট্রিক" বলে। যতটা বিশদে না গিয়ে আমি কৌশলটি কীভাবে কাজ করে তার একটি দৃsp় উপলব্ধি দেওয়ার চেষ্টা করব। বিভিন্ন ভাষায় আরও বিশদ এবং কোডের নমুনার জন্য আমি আপনাকে সেই উত্সটির সাথে পরামর্শ করতে উত্সাহিত করি।

একটি ভাল-পরিচিত বৈচিত্র

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

সমস্ত ব্যাকগ্রাউন্ডের জন্য ধন্যবাদ, zx81 ... তবে রেসিপিটি কী?

কী ফ্যাক্ট

পদ্ধতিটি গ্রুপ 1 ক্যাপচারে ম্যাচটি ফিরিয়ে দেয়। সামগ্রিক ম্যাচটি মোটেও পাত্তা দেয় না।

প্রকৃতপক্ষে, কৌশলটি আমরা চাই না এমন বিভিন্ন প্রসঙ্গে মেলে ( |ওআর / বিকল্পটি ব্যবহার করে এই বিষয়গুলিকে শৃঙ্খলাবদ্ধ করা ) যাতে "সেগুলি নিরপেক্ষ করা যায়"। সমস্ত অযাচিত প্রসঙ্গের সাথে মিলে যাওয়ার পরে, বিকল্পটির চূড়ান্ত অংশটি আমরা যা চাই তা মেলে এবং এটি গ্রুপ 1 এ ধারণ করে।

সাধারণ রেসিপিটি হ'ল

Not_this_context|Not_this_either|StayAway|(WhatYouWant)

এটি মিলবে Not_this_context, তবে একটি অর্থে ম্যাচটি একটি আবর্জনা বিনের মধ্যে চলে যায়, কারণ আমরা সামগ্রিক ম্যাচগুলিতে তাকাব না: আমরা কেবল গ্রুপ 1 ক্যাপচারগুলিকে দেখি।

আপনার ক্ষেত্রে, আপনার অঙ্কগুলি এবং আপনার তিনটি বিষয় উপেক্ষা করার জন্য, আমরা এটি করতে পারি:

s1|s2|s3|(\b\d+\b)

নোট করুন যেহেতু আমরা প্রকৃতপক্ষে s1, s2 এবং s3 এর সাথে মিল না করে এগুলি চেহারার সাথে এড়িয়ে চলার চেষ্টা করেছি, এস 1, এস 2 এবং এস 3 এর স্বতন্ত্র প্রকাশগুলি দিনের মতো পরিষ্কার থাকতে পারে। (এগুলির প্রতিটি পক্ষের তারা সুপ্রেসপ্রেশন |)

পুরো প্রকাশটি এইভাবে লেখা যেতে পারে:

(?m)^.*\.$|\([^\)]*\)|if\(.*?//endif|(\b\d+\b)

এই ডেমোটি দেখুন (তবে নীচের ডান প্যানে ক্যাপচার গ্রুপগুলিতে মনোনিবেশ করুন))

যদি আপনি মানসিকভাবে প্রতিটি |ডিলিমিটারে এই রেজেক্সকে বিভক্ত করার চেষ্টা করেন তবে এটি আসলে কেবলমাত্র চারটি সাধারণ অভিব্যক্তির একটি সিরিজ।

ফ্রি-স্পেসিং সমর্থনকারী স্বাদগুলির জন্য, এটি বিশেষত ভাল পড়ে reads

(?mx)
      ### s1: Match line that ends with a period ###
^.*\.$  
|     ### OR s2: Match anything between parentheses ###
\([^\)]*\)  
|     ### OR s3: Match any if(...//endif block ###
if\(.*?//endif  
|     ### OR capture digits to Group 1 ###
(\b\d+\b)

এটি পড়া এবং বজায় রাখা ব্যতিক্রমী সহজ।

রেজেক্স প্রসারিত হচ্ছে

আপনি যখন আরও পরিস্থিতি s4 এবং s5 উপেক্ষা করতে চান, আপনি এগুলি বাম দিকে আরও বিকল্পে যুক্ত করুন:

s4|s5|s1|s2|s3|(\b\d+\b)

কিভাবে কাজ করে?

আপনি যে বিষয়গুলি চান না তা প্রসঙ্গে বাম দিকে পরিবর্তনের তালিকায় যুক্ত করা হয়েছে: সেগুলি মিলবে, তবে এই সামগ্রিক মিলগুলি কখনই পরীক্ষা করা হয় না, তাই তাদের সাথে মিলানো একটি "আবর্জনার বাক্সে" রাখার একটি উপায়।

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

আমি সবসময় ভিজ্যুয়ালাইজেশনের ভক্ত নই, তবে পদ্ধতিটি কতটা সহজ তা দেখানোর জন্য এটি একটি ভাল কাজ করে does প্রতিটি "লাইন" একটি সম্ভাব্য ম্যাচের সাথে সামঞ্জস্য করে, তবে কেবল নীচের লাইনটি গ্রুপ 1 এ ধরা পড়ে।

নিয়মিত প্রকাশের ভিজ্যুয়ালাইজেশন

ডিবাগেক্স ডেমো

পার্ল / পিসিআরই ভেরিয়েশন

উপরের সাধারণ সমাধানের বিপরীতে, পার্ল এবং পিসিআরই-এর বিভিন্নতার উপস্থিতি রয়েছে যা প্রায়শই এসও-তে দেখা যায়, কমপক্ষে @ ক্যাসিমায়ারেট হিপোলিটি এবং @ হামজা এর মতো রেইজেক্স গডসের হাতে। এইটা:

(?:s1|s2|s3)(*SKIP)(*F)|whatYouWant

তোমার ক্ষেত্রে:

(?m)(?:^.*\.$|\([^()]*\)|if\(.*?//endif)(*SKIP)(*F)|\b\d+\b

এই প্রকরণটি ব্যবহার করা কিছুটা সহজ কারণ কনটেক্সট এস 1, এস 2 এবং এস 3 এর সাথে মেলে এমন সামগ্রীগুলি সহজেই এড়িয়ে চলেছে, সুতরাং আপনাকে গ্রুপ 1 ক্যাপচারগুলি পরিদর্শন করার প্রয়োজন নেই (লক্ষ্য করুন বন্ধনীগুলি চলে গেছে)। মিলগুলি কেবল থাকেwhatYouWant

নোট করুন (*F), (*FAIL)এবং (?!)সব একই জিনিস। আপনি যদি আরও অস্পষ্ট হতে চান তবে আপনি ব্যবহার করতে পারেন(*SKIP)(?!)

এই সংস্করণের জন্য ডেমো

অ্যাপ্লিকেশন

এখানে কিছু সাধারণ সমস্যা রয়েছে যা এই কৌশলটি প্রায়শই সহজেই সমাধান করতে পারে। আপনি লক্ষ্য করবেন যে শব্দটি পছন্দটি এইগুলির মধ্যে কিছু সমস্যা আলাদা করে তুলতে পারে যখন বাস্তবে এটি কার্যত অভিন্ন।

  1. আমি কীভাবে কোনও ট্যাগ ছাড়া কোথাও ফু-র সাথে মেলে ধরতে পারি <a stuff...>...</a>?
  2. আমি কোনও <i>ট্যাগ বা জাভাস্ক্রিপ্ট স্নিপেট (আরও শর্তাবলী) বাদে কীভাবে ফু-র সাথে মেলে ফেলতে পারি ?
  3. এই কালো তালিকায় নেই এমন সমস্ত শব্দের সাথে আমি কীভাবে মিল করব?
  4. আমি কীভাবে কোনও এস.ই.বি. ... এন্ড.উব ব্লকের ভিতরে কিছু উপেক্ষা করতে পারি?
  5. ... এস 1 এস 2 এস 3 বাদে আমি কীভাবে সমস্ত কিছু মেলাতে পারি?

গ্রুপ 1 ক্যাপচার প্রোগ্রাম কিভাবে

আপনি কোড হিসাবে করেন নি, তবে সম্পূর্ণ করার জন্য ... গ্রুপ 1 পরিদর্শন করার কোডটি অবশ্যই আপনার পছন্দের ভাষার উপর নির্ভর করবে। যে কোনও হারে এটি ম্যাচে পরিদর্শন করতে আপনি যে কোডটি ব্যবহার করবেন সেটিতে কয়েকটি লাইন যুক্ত করা উচিত নয়।

যদি সন্দেহ হয়, আমি আপনাকে প্রস্তাবিত নিবন্ধটির কোড নমুনা বিভাগটি দেখে নিন যা বেশ কয়েকটি ভাষার কোড উপস্থাপন করে।

বিকল্প

প্রশ্নের জটিলতা এবং ব্যবহৃত রেজেক্স ইঞ্জিনের উপর নির্ভর করে বিভিন্ন বিকল্প রয়েছে। এখানে দুটি রয়েছে যা একাধিক শর্ত সহ বেশিরভাগ পরিস্থিতিতে প্রয়োগ করতে পারে। আমার দৃষ্টিতে, উভয়ই s1|s2|s3|(whatYouWant)রেসিপিটির মতো প্রায় আকর্ষণীয় নয় , কেবল কারণ যদি পরিষ্কারতা সর্বদা জিততে পারে।

1. তারপর প্রতিস্থাপন।

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

2. চেহারা।

আপনার মূল পোস্টটি দেখিয়েছে যে আপনি কীভাবে একরকম শর্তটিকে লুকোয়ারাউন্ডগুলি ব্যবহার করে বাদ দিতে পারবেন তা বোঝে। আপনি বলেছিলেন যে সি # এটির জন্য দুর্দান্ত এবং আপনি ঠিক বলেছেন তবে এটি একমাত্র বিকল্প নয়। সি #, ভিবি.এনইটি এবং ভিজ্যুয়াল সি ++ এ পাওয়া .NET রেজেক্স স্বাদগুলি যেমন পাইথনে regexপ্রতিস্থাপনের জন্য স্থির-পরীক্ষামূলক মডিউল re, কেবলমাত্র দুটি ইঞ্জিনই আমি জানি যে অসীম-প্রস্থের চেহারাটির পিছনে সমর্থন করে। এই সরঞ্জামগুলির সাহায্যে, এক নজর দেখার পিছনে একটি শর্ত কেবল পিছনে নয় ম্যাচ এবং ম্যাচের বাইরেও তাকানোর যত্ন নিতে পারে, লুকেহেডের সাথে সমন্বয়ের প্রয়োজন বর্জন করে। আরও শর্ত? আরও চেহারা।

আপনি সি # তে এস 3 এর জন্য রেজেক্সকে পুনর্ব্যবহার করে পুরো প্যাটার্নটি দেখতে এইরকম হবে।

(?!.*\.)(?<!\([^()]*(?=\d+[^)]*\)))(?<!if\(\D*(?=\d+.*?//endif))\b\d+\b

তবে এতক্ষণে আপনি জানেন যে আমি এটি সুপারিশ করছি না, তাই না?

মুছে দেওয়া

আপনি হাম মুছতে চাইলে @ হামজা এবং @ জেরি পরামর্শ দিয়েছেন যে মামলার জন্য আমি একটি অতিরিক্ত কৌশল সম্পর্কে উল্লেখ করব WhatYouWant। আপনার মনে আছে যে রেসিপিটি ম্যাচ করার WhatYouWant(এটি গ্রুপ 1 এ ক্যাপচার করা) ছিল s1|s2|s3|(WhatYouWant), তাই না? সমস্ত উদাহরণ মুছতে WhatYouWant, আপনি রেজিটাকে এতে পরিবর্তন করেন

(s1|s2|s3)|WhatYouWant

প্রতিস্থাপনের স্ট্রিংয়ের জন্য, আপনি ব্যবহার করুন $1। এখানে যা ঘটে s1|s2|s3তা হ'ল এটির প্রতিটি উদাহরণের সাথে মিলে যায় প্রতিস্থাপনটি $1সেই দৃষ্টান্তটি নিজের সাথে প্রতিস্থাপন করে (রেফারেন্স করে $1)। অন্যদিকে, যখন WhatYouWantমিলে যায়, এটি একটি খালি গোষ্ঠী দ্বারা প্রতিস্থাপন করা হয় এবং অন্য কিছুই - এবং তাই মুছে ফেলা হয়। এই ডেমোটি দেখুন , এই দুর্দান্ত সংযোজনের পরামর্শ দেওয়ার জন্য আপনাকে @ হামজা এবং @ জেরিকে ধন্যবাদ জানাই।

প্রতিস্থাপন

এটি আমাদের প্রতিস্থাপনে নিয়ে আসে, যার উপর আমি সংক্ষেপে স্পর্শ করব।

  1. কিছুই না দিয়ে প্রতিস্থাপন করার সময়, উপরে "মুছে ফেলা" কৌশলটি দেখুন।
  2. প্রতিস্থাপন করার সময়, পার্ল বা পিসিআরই ব্যবহার করা হলে (*SKIP)(*F), আপনি যা চান ঠিক তার সাথে মেলে উপরে বর্ণিত বিভিন্নতাটি ব্যবহার করুন এবং সরাসরি প্রতিস্থাপন করুন।
  3. অন্যান্য স্বাদে, প্রতিস্থাপন ফাংশন কলের মধ্যে, কলব্যাক বা ল্যাম্বদা ব্যবহার করে ম্যাচটি পরীক্ষা করুন এবং গ্রুপ 1 সেট করা থাকলে প্রতিস্থাপন করুন। যদি আপনার এটির সাহায্যের প্রয়োজন হয় তবে ইতিমধ্যে রেফারেন্স করা নিবন্ধটি আপনাকে বিভিন্ন ভাষায় কোড দেবে।

আনন্দ কর!

না, অপেক্ষা করুন, আরও আছে!

আহ, নাহ, আমি আমার স্মৃতি স্মারকের জন্য এটি পরবর্তী স্প্রিংয়ে প্রকাশ করার জন্য সংরক্ষণ করব।


2
@ কোবি দুই ভাগের উত্তর। হ্যাঁ, গত রাতে লেখাটি চালিয়ে গেলেন এবং নীচে লিখেছিলেন যে আমি এটিতে ঘুমাব এবং পরে পরিপাটি করবো। :) হ্যা কৌশলটি সহজ তবে আমি আপনার ধারণাকে ভাগ করে নিই না যে এটি "মৌলিক" কারণ এটি ব্যতিক্রম সমস্যা সমাধানের জন্য লোকেদের সাধারণ সরঞ্জামগুলির অংশ বলে মনে হয় না। যখন আমি এসওয়ের "ব্যতীত" বা "না" বা "ভিতরে না" সমস্যার জন্য গুগল করি, কেবলমাত্র একটি উত্তর (কোনও ভোট ছাড়াই) এটির পরামর্শ দেয়, অন্যরা কেউই তা করেনি। আমি আপনার উত্তরগুলি দেখিনি, যাইহোক, যা দুর্দান্ত। :)
zx81

2
দুঃখিত, তবে রেক্সের "সেরা কৌশল" কেবল কার্যকরভাবে ( নির্ভরযোগ্যভাবে ) কাজ করে না । বলুন যে আপনি মেলাতে চান Tarzan, তবে ডাবল কোটের ভিতরে থাকা অবস্থায় নয়। দ্য /no|no|(yes)/ট্রিক রেজেক্স এমন কিছু হবে: /"[^"]*"|Tarzan/(পালানো চরগুলি উপেক্ষা করে)। এই অনেক ক্ষেত্রে জন্য কাজ করবে, কিন্তু নিম্নলিখিত বৈধ জাভাস্ক্রিপ্ট টেক্সট প্রয়োগ সম্পূর্ণরূপে ব্যর্থ হলে: var bug1 = 'One " quote here. Should match this Tarzan'; var bug2 = "Should not match this Tarzan";। রেক্সের কৌশল কেবল তখনই কার্যকর হয় যখন সমস্ত সম্ভাব্য কাঠামো মিলে যায় - অন্য কথায় - 100% নির্ভুলতার গ্যারান্টি দেওয়ার জন্য আপনাকে পাঠ্যের পুরোপুরি বিশ্লেষণ করতে হবে।
রডগারুনার

1
দুঃখিত যদি আমি কঠোর মনে করি - এটি অবশ্যই আমার উদ্দেশ্য ছিল না। আমার বক্তব্য (উপরের মূল প্রশ্নের সাথে আমার দ্বিতীয় মন্তব্যে) হ'ল সঠিক সমাধানটি অনুসন্ধানের লক্ষ্য পাঠ্যের উপর নির্ভরশীল। আমার উদাহরণটিতে লক্ষ্য পাঠ্য হিসাবে জাভাস্ক্রিপ্ট উত্স কোড রয়েছে যা একটি একক উদ্ধৃত স্ট্রিংয়ের মধ্যে একটি ডাবল উদ্ধৃতি রয়েছে। এটি ঠিক তত সহজে আক্ষরিক RegExp হতে পারে যেমন: var bug1 = /"[^"]*"|(Tarzan)/gi;এবং এর একই প্রভাব ছিল (এবং এই দ্বিতীয় উদাহরণটি অবশ্যই কোনও প্রান্তের ক্ষেত্রে নয়)। এই কৌশলটি নির্ভরযোগ্যভাবে কাজ করতে ব্যর্থ হয় যেখানে আমি উদ্ধৃত করতে পারে এমন আরও অনেক উদাহরণ রয়েছে।
রডগার্নার

1
@ridgerunner আমি সর্বদা আপনার কাছ থেকে শ্রবণটি উপভোগ করি, এটি আমার কাছে কেবল যুক্তিযুক্তভাবে কঠোর মনে হচ্ছে। যখন আমরা জানি যে আমাদের স্ট্রিংগুলিতে "ভুয়া সতর্কতা" থাকতে পারে, তখন আমরা সকলেই আমাদের নিদর্শনগুলি সামঞ্জস্য করি। উদাহরণস্বরূপ, এমন স্ট্রিংয়ের সাথে মেলে যাতে পলায়নের উদ্ধৃতি থাকতে পারে যা স্ট্রিং ম্যাচারটি ফেলে দিতে পারে, আপনি হয়ত ব্যবহার (?<!\\)"(?:\\"|[^"\r\n])*+" করতে পারেন যদি আপনার কোনও কারণ না থাকে তবে আপনি বড় বন্দুকগুলি টানবেন না। সমাধানের নীতিটি এখনও বৈধ। যদি আমরা বাম দিকে রাখার জন্য কোনও প্যাটার্ন প্রকাশ করতে না পারি তবে এটি অন্যরকম গল্প, আমাদের আলাদা সমাধান দরকার। সমাধানটি যা বিজ্ঞাপন দেয় তা করে।
zx81

1
এই উত্তরটি স্ট্যাক ওভারফ্লো নিয়মিত এক্সপ্রেশনস এফএকিউতে ব্যবহারকারী @ ফঙ্কউইর্ম দ্বারা যুক্ত করা হয়েছে ।
aliteralmind

11

তিনটি পৃথক ম্যাচ করুন এবং ইন-প্রোগ্রামের শর্তসাপেক্ষ যুক্তি ব্যবহার করে তিনটি পরিস্থিতির সমন্বয় পরিচালনা করুন handle আপনাকে একটি জায়ান্ট রেজেক্সে সমস্ত কিছু পরিচালনা করার দরকার নেই।

সম্পাদনা করুন: আমাকে কিছুটা প্রসারিত করুন কারণ প্রশ্নটি আরও আকর্ষণীয় হয়ে উঠেছে :-)

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

using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

public class MatcherWithExceptions {
  private string m_searchStr;
  private Regex m_searchRegex;
  private IEnumerable<Regex> m_exceptionRegexes;

  public string SearchString {
    get { return m_searchStr; }
    set {
      m_searchStr = value;
      m_searchRegex = new Regex(value);
    }
  }

  public string[] ExceptionStrings {
    set { m_exceptionRegexes = from es in value select new Regex(es); }
  }

  public bool IsMatch(string testStr) {
    return (
      m_searchRegex.IsMatch(testStr)
      && !m_exceptionRegexes.Any(er => er.IsMatch(testStr))
    );
  }
}

public class App {
  public static void Main() {
    var mwe = new MatcherWithExceptions();

    // Set up the matcher object.
    mwe.SearchString = @"\b\d{5}\b";
    mwe.ExceptionStrings = new string[] {
      @"\.$"
    , @"\(.*" + mwe.SearchString + @".*\)"
    , @"if\(.*" + mwe.SearchString + @".*//endif"
    };

    var testStrs = new string[] {
      "1." // False
    , "11111." // False
    , "(11111)" // False
    , "if(11111//endif" // False
    , "if(11111" // True
    , "11111" // True
    };

    // Perform the tests.
    foreach (var ts in testStrs) {
      System.Console.WriteLine(mwe.IsMatch(ts));
    }
  }
}

সুতরাং উপরে, আমরা অনুসন্ধান স্ট্রিং (পাঁচটি সংখ্যার), একাধিক ব্যতিক্রম স্ট্রিং (আপনার সেট আপ S1 , S2 এবং S3 ), এবং তারপর বিভিন্ন পরীক্ষা স্ট্রিং বিরুদ্ধে মেলানোর চেষ্টা। মুদ্রিত ফলাফলগুলি প্রতিটি পরীক্ষার স্ট্রিংয়ের পরবর্তী মন্তব্যে দেখানো উচিত।


2
আপনি বলতে চাইছেন সারিবদ্ধভাবে তিনটি রেজেক্সের মতো? রেজেক্স 1 পরিস্থিতি 1 টি সরিয়ে ফেলবে (সম্ভবত কেবল খারাপ অঙ্ক মুছবে), আর 2 এস 2 সরান, আর 3 এস 3 সরান এবং অঙ্কগুলি বাকী মেলে? এটি আকর্ষণীয় ধারণা।
হ্যান্স শিন্ডলার

হা, অবশ্যই, সে কারণেই আমি আপনাকে উজ্জীবিত করেছি। :) আমাকে ভুল করবেন না, আমি এখনও মনে করি যে এই বিশেষ ক্ষেত্রে আমার উত্তরটি আরও দক্ষ এবং রক্ষণাবেক্ষণযোগ্য। আমি গতকাল মুক্ত-ব্যবধান সংস্করণটি দেখেছি? এটি ওয়ান-পাস এবং পড়া এবং রক্ষণাবেক্ষণের পক্ষে ব্যতিক্রমী easy তবে আমি আপনার কাজ এবং আপনার প্রসারিত উত্তর পছন্দ করি। দুঃখিত আমি আবার upvote করতে পারবেন না, না হলে আমি। :)
zx81

2

আপনার প্রয়োজনীয়তা যে এটি সমস্ত ক্ষেত্রে সন্তুষ্ট করা অসম্ভব প্যারেনের ভিতরে নেই। যথা, আপনি যদি কোনওভাবে (বাম এবং )ডানদিকে কোনও সন্ধান করতে পারেন তবে এর অর্থ সর্বদা এই নয় যে আপনি পেরেনের ভিতরে রয়েছেন। যেমন।

(....) + 55555 + (.....)- পেরেনের ভিতরে এখনও নেই (এবং )বাম এবং ডানদিকে রয়েছে

এখন আপনি নিজেকে চতুর মনে (করতে পারেন )এবং ডানদিকে বিপরীতে মুখোমুখি না হলে কেবল বাম দিকে তাকান। এটি এই ক্ষেত্রে কাজ করবে না:

((.....) + 55555 + (.....))- পেরেনগুলির ভিতরে এমনকি বন্ধ )এবং (বাম এবং ডানদিকে থাকলেও ।

আপনি রেজেনেক্স ব্যবহার করে প্যারেনের ভিতরে রয়েছেন কিনা তা খুঁজে পাওয়া অসম্ভব, কেননা রেজেক্স কতটি পেরেন খোলা হয়েছে এবং কতগুলি বন্ধ হয়েছে তা গণনা করতে পারে না।

এই সহজ কাজটি বিবেচনা করুন: রেজেেক্স ব্যবহার করে, কোনও স্ট্রিংয়ের সমস্ত (সম্ভবত নেস্টেড) বন্ধন বন্ধ আছে কিনা (তা সন্ধান করুন, এটি আপনার সন্ধান করা প্রত্যেকটির জন্যই )। আপনি এটি আবিষ্কার করতে পারবেন যে এটি সমাধান করা অসম্ভব এবং আপনি যদি রেজেক্সের সাহায্যে এটি সমাধান করতে না পারেন তবে আপনি যদি কোনও শব্দটি সমস্ত ক্ষেত্রে প্যারেন্সের ভিতরে থাকেন তবে আপনি বুঝতে পারবেন না যেহেতু আপনি স্ট্রিংয়ের কিছু অবস্থান থেকে বের করতে পারবেন না যদি সমস্ত পূর্ববর্তী (একটি অনুরূপ আছে )


2
নেস্টেড প্রথম বন্ধনী সম্পর্কে কেউ কিছু বলেনি, এবং আপনার কেস # 1 zx81 এর উত্তর দিয়ে ঠিক জরিমানা করা হয়েছে।
ড্যান বেচার্ড

সুন্দর ভাবনার জন্য আপনাকে ধন্যবাদ :) তবে নেস্টেড প্রথম বন্ধনী এই প্রশ্নের জন্য আমাকে উদ্বিগ্ন করে না এটি খারাপ পরিস্থিতি সম্পর্কে ধারণা সম্পর্কে আরও বেশি s1 s2 s3
হ্যানস শিন্ডলার

অবশ্যই এটা অসম্ভব! ঠিক এই কারণেই আপনাকে বর্তমানে যে প্যারেনসটি পার্স করছেন তার সন্ধান করতে হবে।
মিঃ ওয়ান্ডারফুল

ওয়েল, যদি আপনি কোনও ধরণের সিএফজিকে পার্স করছেন যেমন ওপি করছে বলে মনে হচ্ছে, তবে এলএলআর বা অনুরূপ পার্সার তৈরির মাধ্যমে আপনাকে আরও ভালভাবে পরিবেশন করা হবে যার এতে সমস্যা নেই।
রকএল

2

হান্স যদি আপনি কিছু মনে করেন না তবে আমি আপনার প্রতিবেশীর ওয়াশিং মেশিনটি পার্ল নামে ব্যবহার করেছি :)

সম্পাদিত: সিউডো কোডের নীচে:

  loop through input
  if line contains 'if(' set skip=true
        if skip= true do nothing
        else
           if line match '\b\d{5}\b' set s0=true
           if line does not match s1 condition  set s1=true
           if line does not match s2 condition  set s2=true
           if s0,s1,s2 are true print line 
  if line contains '//endif' set skip=false

ফাইল দেওয়া হয়েছে। টেক্সট:

tiago@dell:~$ cat input.txt 
this is a text
it should match 12345
if(
it should not match 12345
//endif 
it should match 12345
it should not match 12345.
it should not match ( blabla 12345  blablabla )
it should not match ( 12345 )
it should match 12345

এবং স্ক্রিপ্ট ভ্যালিডেটর.পিএল:

tiago@dell:~$ cat validator.pl 
#! /usr/bin/perl
use warnings;
use strict;
use Data::Dumper;

sub validate_s0 {
    my $line = $_[0];
    if ( $line =~ \d{5/ ){
        return "true";
    }
    return "false";
}

sub validate_s1 {
    my $line = $_[0];
    if ( $line =~ /\.$/ ){
        return "false";
    }
    return "true";
}

sub validate_s2 {
    my $line = $_[0];
    if ( $line =~ /.*?\(.*\d{5.*?\).*/ ){
        return "false";
    }
    return "true";
}

my $skip = "false";
while (<>){
    my $line = $_; 

    if( $line =~ /if\(/ ){
       $skip = "true";  
    }

    if ( $skip eq "false" ) {
        my $s0_status = validate_s0 "$line"; 
        my $s1_status = validate_s1 "$line";
        my $s2_status = validate_s2 "$line";

        if ( $s0_status eq "true"){
            if ( $s1_status eq "true"){
                if ( $s2_status eq "true"){
                    print "$line";
                }
            }
        }
    } 

    if ( $line =~ /\/\/endif/) {
        $skip="false";
    }
}

এক্সেকিউশন:

tiago @ ডেল: $ $ বিড়াল ইনপুট.টেক্সট | পার্ল ভ্যালিডেটর.পিএল
এটি 12345 এর সাথে মেলে
এটি 12345 এর সাথে মেলে
এটি 12345 এর সাথে মেলে

2

এটি আপনাকে সাহায্য করবে কিনা তা নিশ্চিত নয় তবে আমি নিম্নলিখিত অনুমানগুলি বিবেচনা করে একটি সমাধান সরবরাহ করছি -

  1. সমস্ত শর্ত পরীক্ষা করতে আপনার একটি মার্জিত সমাধান দরকার
  2. পরিস্থিতি ভবিষ্যতে এবং যে কোনও সময় পরিবর্তিত হতে পারে।
  3. একটি শর্ত অন্যের উপর নির্ভর করে না।

তবে আমি নিম্নলিখিতগুলিও বিবেচনা করেছি -

  1. প্রদত্ত ফাইলটির এতে ন্যূনতম ত্রুটি রয়েছে। যদি এটি না হয় তবে আমার কোডটিকে সামাল দিতে কিছু সংশোধন দরকার হতে পারে।
  2. আমি if(ব্লকগুলি ট্র্যাক রাখতে স্ট্যাক ব্যবহার করেছি ।

ঠিক আছে এখানে সমাধান -

কনফিগারযোগ্য পার্সারগুলি প্রয়োগ করতে আমি সি # এবং এর সাথে এমইএফ (মাইক্রোসফ্ট এক্সটেনসিবিলিটি ফ্রেমওয়ার্ক) ব্যবহার করেছি। ধারণাটি হ'ল, পার্স করার জন্য একটি একক পার্সার এবং কনফিগারযোগ্য বৈধকরণকারী শ্রেণীর একটি তালিকা লাইনটি যাচাই করতে এবং বৈধতার ভিত্তিতে সত্য বা মিথ্যা প্রত্যাবর্তনের জন্য ব্যবহার করুন। তারপরে আপনি যে কোনও সময় যেকোন বৈধ সংযোজনকারীকে যুক্ত বা সরাতে বা আপনার পছন্দ হলে নতুন যুক্ত করতে পারেন। আপনি ইতিমধ্যে এস 1, এস 2 এবং এস 3 এর জন্য ইতিমধ্যে প্রয়োগ করেছি, পয়েন্ট 3 এ ক্লাস চেক করুন আপনার যদি ভবিষ্যতে প্রয়োজন হয় তবে আপনাকে এস 4, এস 5 এর জন্য ক্লাস যুক্ত করতে হবে।

  1. প্রথমে ইন্টারফেস তৈরি করুন -

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace FileParserDemo.Contracts
    {
        public interface IParser
        {
            String[] GetMatchedLines(String filename);
        }
    
        public interface IPatternMatcher
        {
            Boolean IsMatched(String line, Stack<string> stack);
        }
    }
  2. তারপরে ফাইল রিডার এবং পরীক্ষক আসে -

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using FileParserDemo.Contracts;
    using System.ComponentModel.Composition.Hosting;
    using System.ComponentModel.Composition;
    using System.IO;
    using System.Collections;
    
    namespace FileParserDemo.Parsers
    {
        public class Parser : IParser
        {
            [ImportMany]
            IEnumerable<Lazy<IPatternMatcher>> parsers;
            private CompositionContainer _container;
    
            public void ComposeParts()
            {
                var catalog = new AggregateCatalog();
                catalog.Catalogs.Add(new AssemblyCatalog(typeof(IParser).Assembly));
                _container = new CompositionContainer(catalog);
                try
                {
                    this._container.ComposeParts(this);
                }
                catch
                {
    
                }
            }
    
            public String[] GetMatchedLines(String filename)
            {
                var matched = new List<String>();
                var stack = new Stack<string>();
                using (StreamReader sr = File.OpenText(filename))
                {
                    String line = "";
                    while (!sr.EndOfStream)
                    {
                        line = sr.ReadLine();
                        var m = true;
                        foreach(var matcher in this.parsers){
                            m = m && matcher.Value.IsMatched(line, stack);
                        }
                        if (m)
                        {
                            matched.Add(line);
                        }
                     }
                }
                return matched.ToArray();
            }
        }
    }
  3. তারপরে স্বতন্ত্র চেকারগুলির বাস্তবায়ন আসে, শ্রেণীর নামগুলি স্বতঃস্পষ্ট বর্ণনামূলক, তাই তাদের আরও বিবরণ প্রয়োজন বলে আমি মনে করি না।

    using FileParserDemo.Contracts;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading.Tasks;
    
    namespace FileParserDemo.PatternMatchers
    {
        [Export(typeof(IPatternMatcher))]
        public class MatchAllNumbers : IPatternMatcher
        {
            public Boolean IsMatched(String line, Stack<string> stack)
            {
                var regex = new Regex("\\d+");
                return regex.IsMatch(line);
            }
        }
    
        [Export(typeof(IPatternMatcher))]
        public class RemoveIfBlock : IPatternMatcher
        {
            public Boolean IsMatched(String line, Stack<string> stack)
            {
                var regex = new Regex("if\\(");
                if (regex.IsMatch(line))
                {
                    foreach (var m in regex.Matches(line))
                    {
                        //push the if
                        stack.Push(m.ToString());
                    }
                    //ignore current line, and will validate on next line with stack
                    return true;
                }
                regex = new Regex("//endif");
                if (regex.IsMatch(line))
                {
                    foreach (var m in regex.Matches(line))
                    {
                        stack.Pop();
                    }
                }
                return stack.Count == 0; //if stack has an item then ignoring this block
            }
        }
    
        [Export(typeof(IPatternMatcher))]
        public class RemoveWithEndPeriod : IPatternMatcher
        {
            public Boolean IsMatched(String line, Stack<string> stack)
            {
                var regex = new Regex("(?m)(?!\\d+.*?\\.$)\\d+");
                return regex.IsMatch(line);
            }
        }
    
    
        [Export(typeof(IPatternMatcher))]
        public class RemoveWithInParenthesis : IPatternMatcher
        {
            public Boolean IsMatched(String line, Stack<string> stack)
            {
                var regex = new Regex("\\(.*\\d+.*\\)");
                return !regex.IsMatch(line);
            }
        }
    }
  4. কার্যক্রম -

    using FileParserDemo.Contracts;
    using FileParserDemo.Parsers;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace FileParserDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                var parser = new Parser();
                parser.ComposeParts();
                var matches = parser.GetMatchedLines(Path.GetFullPath("test.txt"));
                foreach (var s in matches)
                {
                    Console.WriteLine(s);
                }
                Console.ReadLine();
            }
        }
    }

পরীক্ষার জন্য আমি @ টিয়াগো'র নমুনা ফাইলটি গ্রহণ করেছি Test.txtযা নিম্নলিখিত রেখাগুলি ছিল -

this is a text
it should match 12345
if(
it should not match 12345
//endif 
it should match 12345
it should not match 12345.
it should not match ( blabla 12345  blablabla )
it should not match ( 12345 )
it should match 12345

আউটপুট দেয় -

it should match 12345
it should match 12345
it should match 12345

জানেন না এটি আপনাকে সাহায্য করবে কিনা বা না, আমি এটি নিয়ে মজা করার সময় কাটিয়েছি .... :)

এর সাথে সর্বোত্তম অংশটি হ'ল, একটি নতুন শর্ত যুক্ত করার জন্য আপনাকে যা করতে হবে তা হল একটি বাস্তবায়ন সরবরাহ করা IPatternMatcher, এটি স্বয়ংক্রিয়ভাবে কল হয়ে যাবে এবং এইভাবে বৈধ হবে।


2

@ Zx81 এর মতো (*SKIP)(*F)তবে নেতিবাচক বর্ণনাহীন দৃ using়তা ব্যবহারের সাথে।

(?m)(?:if\(.*?\/\/endif|\([^()]*\))(*SKIP)(*F)|\b\d+\b(?!.*\.$)

ডেমো

অজগরে, আমি এটি সহজেই করতাম,

import re
string = """cat 123 sat.
I like 000 not (456) though 111 is fine
222 if(  //endif if(cat==789 stuff  //endif   333"""
for line in string.split('\n'):                                  # Split the input according to the `\n` character and then iterate over the parts.
    if not line.endswith('.'):                                   # Don't consider the part which ends with a dot.
        for i in re.split(r'\([^()]*\)|if\(.*?//endif', line):   # Again split the part by brackets or if condition which endswith `//endif` and then iterate over the inner parts.
            for j in re.findall(r'\b\d+\b', i):                  # Then find all the numbers which are present inside the inner parts and then loop through the fetched numbers.
                print(j)                                         # Prints the number one ny one.

আউটপুট:

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