লোভী বনাম অনিচ্ছুক বনাম প্যাসেসিভ কোয়ান্টিফায়ার্স


357

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

বিশেষত, নিম্নলিখিত উদাহরণে:

Enter your regex: .*foo  // greedy quantifier
Enter input string to search: xfooxxxxxxfoo
I found the text "xfooxxxxxxfoo" starting at index 0 and ending at index 13.

Enter your regex: .*?foo  // reluctant quantifier
Enter input string to search: xfooxxxxxxfoo
I found the text "xfoo" starting at index 0 and ending at index 4.
I found the text "xxxxxxfoo" starting at index 4 and ending at index 13.

Enter your regex: .*+foo // possessive quantifier
Enter input string to search: xfooxxxxxxfoo
No match found.

ব্যাখ্যায় পুরো ইনপুট স্ট্রিং খাওয়ার উল্লেখ করা হয়েছে, চিঠিগুলি গ্রাস করা হয়েছে , ম্যাচার ব্যাক আপ বন্ধ রয়েছে , "ফু" এর ডানদিকের ঘটনাটি পুনরায় সাজানো হয়েছে ইত্যাদি tions

দুর্ভাগ্যক্রমে, সুন্দর রূপক থাকা সত্ত্বেও, আমি কাকে খেয়েছি তা এখনও বুঝতে পারি না ... আপনি কি এমন একটি টিউটোরিয়াল জানেন যা নিয়মিত এক্সপ্রেশন ইঞ্জিনগুলি কীভাবে কাজ করে তা ব্যাখ্যা করে (সংক্ষেপে) ?

বিকল্পভাবে, যদি কেউ নিম্নলিখিত অনুচ্ছেদে কিছু আলাদাভাবে ব্যাখ্যা করতে পারেন, তবে এটির প্রশংসা হবে:

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

দ্বিতীয় উদাহরণটি অবশ্য অনিচ্ছুক, তাই এটি প্রথমে ( কাদের দ্বারা? ) "কিছুই না" গ্রাস করে শুরু হয় । কারণ "foo বিন্যাস" STRING শুরুতে বলে মনে হচ্ছে না, এটা গেলা করতে বাধ্য এর ( যারা swallows?) প্রথম চিঠি (একটি "X"), যা 0 এবং 4. আমাদের পরীক্ষা সাজ প্রথম ম্যাচ আরম্ভ করে প্রক্রিয়া অব্যাহত ইনপুট স্ট্রিং অবসন্ন না হওয়া পর্যন্ত। এটি 4 এবং 13 এ অন্য একটি মিল খুঁজে পেয়েছে।

তৃতীয় উদাহরণটি একটি মিল খুঁজে পেতে ব্যর্থ হয়েছে কারণ কোয়ান্টিফায়ার মালিকানাধীন। এই ক্ষেত্রে, সম্পূর্ণ ইনপুট স্ট্রিংটি গ্রাস করে * * +, ( কীভাবে? ) অভিব্যক্তিটির শেষে "ফু" সন্তুষ্ট করার জন্য কিছুই রেখে যায় না। যে পরিস্থিতিতে আপনি কখনই ব্যাক ব্যাক না করে সমস্ত কিছু বাজেয়াপ্ত করতে চান এমন পরিস্থিতিগুলির জন্য একটি প্রাপ্য কোয়ান্টিফায়ার ব্যবহার করুন ( ব্যাক অফের অর্থ কী? ); ম্যাচটি তাত্ক্ষণিকভাবে খুঁজে পাওয়া যায় না এমন ক্ষেত্রে এটি সমতুল্য লোভী পরিমাণকে ছাড়িয়ে যাবে per


22
সর্বধিক quantifiers পছন্দ *, +এবং ?হয় লোভী। সংক্ষিপ্ত quantifiers পছন্দ *?, +?এবং ??হয় অলস। সম্বন্ধসূচক quantifiers পছন্দ *+, ++এবং ?+হয় চটচটে।
tchrist

6
এই প্রশ্নটি স্ট্যাক ওভারফ্লো নিয়মিত এক্সপ্রেশন FAQ এ যুক্ত করা হয়েছে , "কোয়ান্টিফায়ার্স> পার্থক্য সম্পর্কে আরও ..." এর অধীনে।
aliteralmind 0

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

উত্তর:


495

আমি একটা শট দেব।

একটি লোভী কোয়ান্টিফায়ার প্রথম যতটা সম্ভব মেলে। সুতরাং .*পুরো স্ট্রিং মেলে। তারপরে ম্যাচারটি fনিম্নলিখিতগুলির সাথে মেলে চেষ্টা করে , তবে কোনও অক্ষর বাকী নেই। সুতরাং এটি "ব্যাকট্র্যাকস", লোভী কোয়ান্টিফায়ারকে আরও একটি কম চরিত্রের সাথে মেলে (স্ট্রিংয়ের শেষে "ও" রেখে গেছে)। এটি এখনও fরেজেজেসের সাথে মেলে না , সুতরাং এটি আরও একটি পদক্ষেপের পিছনে পিছনে ফিরে আসে, লোভী কোয়ান্টিফায়ারটিকে আবার একটি কম চরিত্রের সাথে মিলিয়ে তোলে (স্ট্রিংয়ের শেষে "oo" রেখে যায়)। এটি এখনওf রেজেজেসের সাথে মেলে না , সুতরাং এটি আরও একটি পদক্ষেপ ব্যাকট্র্যাক করে (স্ট্রিংয়ের শেষে "ফু" ছেড়েছে)। এখন, ম্যাচারটি অবশেষে রেজেক্সে মেলে f,ooখুব মিলেছে। সফল!

একটি অনিচ্ছুক বা "অ-লোভী" কোয়ান্টিফায়ার প্রথমটি যতটা সম্ভব সামান্য। সুতরাং .*ম্যাচগুলি প্রথমে কিছু মিলছে না, পুরো স্ট্রিংটি ম্যাচ না করে। তারপরে ম্যাচারটি fনিম্নলিখিতগুলির সাথে মিলানোর চেষ্টা করে তবে স্ট্রিংয়ের সাথে মেলে না এমন অংশটি "x" দিয়ে শুরু হয় যাতে এটি কাজ করে না। সুতরাং ম্যাচার ব্যাকট্র্যাকগুলি, অ-লোভী কোয়ান্টিফায়ারটিকে আরও একটি চরিত্রের সাথে মেলে (এখন এটি "x" এর সাথে মেলে, "fooxxxxxxfoo" তুলনামূলকভাবে ছেড়ে গেছে)। তারপরে এটি ম্যাচটি চেষ্টা করে f, যা সফল হয়, এবং oপরবর্তীটিও oরেজেক্স ম্যাচে। সফল!

আপনার উদাহরণস্বরূপ, এটি একই প্রক্রিয়াটি অনুসরণ করে স্ট্রিংয়ের অবশিষ্ট তুলনামূলক অংশ "xxxxxxfoo" দিয়ে প্রক্রিয়াটি শুরু করে।

একটি অধিকারী কোয়ানটিফায়ার হ'ল লোভী কোয়ান্টিফায়ারের মতো, তবে এটি পিছনে যায় না। সুতরাং এটি .*সম্পূর্ণ স্ট্রিংয়ের সাথে মিল রেখে শুরু হয় , কিছুই মিলবে না। তারপরে fরেজেক্সের সাথে এটির মিলের জন্য আর কিছুই অবশিষ্ট নেই । যেহেতু অধিকারী কোয়ান্টিফায়ার ব্যাকট্র্যাক করে না, ম্যাচটি সেখানে ব্যর্থ।


15
+1 ভাল উত্তর। আমি কেবল যুক্ত করব: নিয়মিত প্রকাশ (
মাসের

@ অ্যানোমিকে কিছুটা দেরি হলেও, অধিকারী অংশে, আমি মনে করি আপনি বোঝাতে চেয়েছিলেন তাই এটি শুরু হয়েছিল .*+ ("+" দেখুন)
আরডি

3
অধিকারী কোয়ান্টিফায়ার ঠিক তখন কী করে? যদি এটি মেলে না? (এর অর্থ কী, এটির পরে যদি আপনি অক্ষর নাও রাখতে পারেন)
22:48

4
@ রিলিপস: আপনি এটিকে এমন পরিস্থিতিতে ব্যবহার করবেন যেখানে আপনি জানেন যে ব্যাকট্র্যাকিং কোনও কাজ করবে না, সম্ভবত .*+সবকিছুর সাথে মেলে না । উদাহরণস্বরূপ, যদি আপনার কোনও প্যাটার্ন [xyz]*fooথাকে তবে এক্স, ওয়াই এবং জেড [xyz]*বিটের পিছনে মিলে যাওয়া কোনও উপায়ই নীচের fooবিটটির সাথে মিলবে না, তাই আপনি বিষয়টিকে অধিকারী করে গতি বাড়িয়ে দিতে পারেন।
অ্যানোমি

4
@ মুডবুম, এমন শূন্য কেস এখনও রয়েছে (গাণিতিক সত্য) যেখানে অধিকারী কোয়ান্টিফায়াররা এমন একটি ম্যাচ তৈরি করবে যা সাধারণ লোভী কোয়ান্টিফায়ার দ্বারা উত্পাদিত হবে না। সেখানে অনিয়মিত ক্ষেত্রে যেখানে তারা একটি উত্পাদন করা হবে হয় কোনো মিল যখন লোভী quantifiers একটি উত্পাদন করবে ম্যাচ। সমস্ত অন্যান্য ক্ষেত্রে (যেখানে লোভী এবং অধিকারী একই ফলাফল প্রকাশ করে), অধিকারী কোয়ান্টিফায়াররা একটি পারফরম্যান্স লাভ দেয়।
ওয়াইল্ডকার্ড

49

দৃশ্যটি দেখার জন্য এটি কেবল আমার অনুশীলনের ফলাফল-

দৃষ্টি নির্ভর ছবি


3
আমি মনে করি ব্যতীত শেষ কেসটি, অধিকারী, এন পাস হওয়া উচিত নয় - কেবল একবারে পুরো স্ট্রিংটি ধরুন।
আপনার মোডগুলিকে ভালভাবে

@ ফাইজম আমার মনে হয় এখন ঠিক আছে?
এসআইস্লাম

1
ভিজ্যুয়াল ব্যাখ্যার জন্য ধন্যবাদ :)
লার্স মোয়েললেকেন

ইন EXPRESSION .*?foo(), should't [f] [o] [o]আয়তক্ষেত্র হলুদ হতে 5th pass?
টোনিক্স

1
@ টোনিক্স হ্যাঁ! ইয়েলো রং এক্সপ্রেশনে মিলেছে অংশ জন্য সম্পন্ন করা প্রয়োজন .*?fooএবং .*+foo
এসআইস্লাম

24

আমি 'রেগরিজিট' বা 'ব্যাকিং অফ' এর আগের শব্দটি আগে শুনিনি; এগুলিকে প্রতিস্থাপন করবে এমন বাক্যটি হ'ল "ব্যাকট্র্যাকিং", তবে 'রিগ্রিজিট' এমন কোনও বাক্য বলে মনে হচ্ছে "ব্যাকট্র্যাকিংয়ের আগে যে বিষয়বস্তুটি সাময়িকভাবে গ্রহণ করা হয়েছিল তা আবার তা ফেলে দেওয়ার জন্য" for

বেশিরভাগ রেজেক্স ইঞ্জিনগুলি সম্পর্কে উপলব্ধি করার জন্য গুরুত্বপূর্ণ বিষয়টি হ'ল তারা ব্যাকট্র্যাকিং করছে : তারা রেজেক্সের সম্পূর্ণ বিষয়বস্তুগুলির সাথে মেলে চেষ্টা করার সময় সাময়িকভাবে একটি সম্ভাব্য, আংশিক মিল গ্রহণ করবে । প্রথম প্রয়াসে যদি রেজেক্স সম্পূর্ণরূপে মেলে না যায়, তবে রেজেক্স ইঞ্জিনটি এর একটি ম্যাচে ব্যাকট্র্যাক করবে । সদৃশ চেষ্টা করবে *, +, ?, পরিবর্তনের মাঝে বা {n,m}পুনরাবৃত্তি ভিন্নভাবে, আবার চেষ্টা করুন। (এবং হ্যাঁ, এই প্রক্রিয়াটি দীর্ঘ সময় নিতে পারে ))

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

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

সুতরাং ম্যাচার আস্তে আস্তে ( ডান থেকে বাম? ) একবারে একটি চিঠি ব্যাক আপ করার আগে পর্যন্ত "ফু" এর ডানদিকের ঘটনাটি পুনরায় সীমাবদ্ধ না করা পর্যন্ত (এর অর্থ কী? ), যেখানে

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

পয়েন্টটি ম্যাচটি সফল হয় এবং অনুসন্ধান শেষ হয়।

দ্বিতীয় উদাহরণটি অবশ্য অনিচ্ছুক, তাই এটি প্রথমে ( কাদের দ্বারা? ) "কিছুই না" গ্রাস করে শুরু হয় । কারণ "ফু"

প্রারম্ভিক কিছুই গ্রাস করে না .?*, যা সবচেয়ে কম পরিমাণে কিছু খায় যা বাকি রেগেক্সকে ম্যাচ করার অনুমতি দেয়।

স্ট্রিংয়ের শুরুতে উপস্থিত হয় না, এটি গিলে ফেলতে বাধ্য হয় ( কে গিলেছে?) the

আবার .?*প্রথম অক্ষরটি গ্রাস করে, সংক্ষিপ্ততম ম্যাচের সাথে পুরো রেজেক্সকে মেলাতে প্রাথমিক ব্যর্থতার ব্যাকট্র্যাক করার পরে। (এই ক্ষেত্রে, রেজেক্স ইঞ্জিনটি ম্যাচটি .*?বাম থেকে ডানদিকে প্রসারিত করছে , কারণ .*?অনিচ্ছুক))

প্রথম অক্ষর (একটি "x"), যা প্রথম ম্যাচটি 0 এবং 4 এ ট্রিগার করে the ইনপুট স্ট্রিং শেষ না হওয়া অবধি আমাদের পরীক্ষার জোতা প্রক্রিয়াটি অব্যাহত রাখে। এটি 4 এবং 13 এ অন্য একটি মিল খুঁজে পেয়েছে।

তৃতীয় উদাহরণটি একটি মিল খুঁজে পেতে ব্যর্থ হয়েছে কারণ কোয়ান্টিফায়ার মালিকানাধীন। এই ক্ষেত্রে, পুরো ইনপুট স্ট্রিংটি গ্রাস করে। * +, ( কিভাবে? )

.*+যতটা সম্ভব গ্রাস করবে এবং পুরো যখন রেজেক্স কোনও ম্যাচ সন্ধান করতে ব্যর্থ হবে তখন নতুন ম্যাচগুলি সন্ধান করতে ব্যাকট্র্যাক করবে না । কারণ সম্বন্ধসূচক ফর্ম backtracking না সঞ্চালন না করে, আপনি সম্ভবত সঙ্গে অনেক ব্যবহার দেখতে পাবেন না .*+, বরং চরিত্র শ্রেণীর বা অনুরূপ সীমাবদ্ধতা সহ: account: [[:digit:]]*+ phone: [[:digit:]]*+

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

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

অভিব্যক্তিটির শেষে "ফু" সন্তুষ্ট করার জন্য কিছুই রেখে যায় না। যে পরিস্থিতিতে আপনি কখনই ব্যাক ব্যাক না করে সমস্ত কিছু বাজেয়াপ্ত করতে চান এমন পরিস্থিতিগুলির জন্য একটি প্রাপ্য কোয়ান্টিফায়ার ব্যবহার করুন ( ব্যাক অফের অর্থ কী? ); এটি ছাড়িয়ে যাবে

এই প্রসঙ্গে "ব্যাক অফ অফ" এর অর্থ "ব্যাকট্র্যাকিং" - অন্য আংশিক ম্যাচ চেষ্টা করার জন্য একটি অস্থায়ী আংশিক ম্যাচ ফেলে দেওয়া, যা সফল হতে পারে বা নাও হতে পারে।

ম্যাচগুলি তত্ক্ষণাত সন্ধান না পাওয়া ক্ষেত্রে সমতুল্য লোভী কোয়ান্টিফায়ার।


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

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

1
@ উইল্ডকার্ড, মন্তব্যের জন্য ধন্যবাদ; এটি ব্যাখ্যা করতে পারে যে আমাকে কেন একটি উদাহরণ হাজির করতে সমস্যা হয়েছিল। হে হে।
sarnold

19

http://swtch.com/~rsc/regexp/regexp1.html

আমি নিশ্চিত নই যে এটি ইন্টারনেটে সেরা ব্যাখ্যা, তবে এটি যুক্তিসঙ্গতভাবে ভাল লিখিত এবং যথাযথভাবে বিশদ, এবং আমি এটিতে ফিরে আসতে চাই keep আপনি এটি পরীক্ষা করে দেখতে চাইবেন।

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

এই প্রক্রিয়াটি পুনরাবৃত্তভাবে ব্যবহৃত হয়: প্রদত্ত নিয়মিত অভিব্যক্তির সাথে একটি স্ট্রিংয়ের মিলের প্রয়াসে ইঞ্জিন নিয়মিত প্রকাশকে টুকরো টুকরো টুকরো করে বিভক্ত করবে এবং প্রতিটি টুকরাতে পৃথকভাবে অ্যালগরিদম প্রয়োগ করবে।

লোভী, অনিচ্ছুক এবং অধিকারী কোয়ান্টিফায়ারগুলির মধ্যে পার্থক্য প্রবেশ করে যখন ইঞ্জিন তার স্ট্রিংয়ের কোন অংশটির সাথে মেলে ধরার চেষ্টা করে এবং সেই পছন্দটি যদি প্রথমবার কাজ না করে তবে কীভাবে পরিবর্তন করা যায় of নিয়মগুলি নিম্নরূপ:

  • একটি লোভী কোয়ান্টিফায়ার ইঞ্জিনটিকে পুরো স্ট্রিং (বা কমপক্ষে, এর সবগুলি আগে থেকেই নিয়মিত অভিব্যক্তির পূর্ববর্তী অংশগুলির সাথে মেলে না) দিয়ে শুরু করতে বলে এবং পরীক্ষা করে এটি রিজেক্সের সাথে মেলে কিনা। যদি তাই হয়, দুর্দান্ত; ইঞ্জিনটি বাকী রিজেক্সের সাথে চালিয়ে যেতে পারে। যদি তা না হয় তবে এটি আবার চেষ্টা করে, তবে স্ট্রিংয়ের অংশটি বাদ দিয়ে একটি অক্ষর (সর্বশেষ একটি) ছাঁটাই করা যায় checked যদি এটি কাজ না করে, তবে এটি অন্য একটি চরিত্র ইত্যাদি ছাঁটাই করে দেয় তাই লোভী কোয়ান্টিফায়ার দীর্ঘতম থেকে স্বল্পতম পর্যন্ত সম্ভাব্য ম্যাচগুলি পরীক্ষা করে।

  • একটি অনিচ্ছুক কোয়ান্টিফায়ার ইঞ্জিনটিকে স্ট্রিংয়ের সবচেয়ে সংক্ষিপ্ততম টুকরো দিয়ে শুরু করতে বলে। যদি এটি মেলে, ইঞ্জিন চালিয়ে যেতে পারে; যদি না হয়, এটা যোগ করা স্ট্রিংয়ের বিভাগে একটি অক্ষর হচ্ছে চেক করা এবং চেষ্টা করে, এবং তাই হওয়া পর্যন্ত একটি ম্যাচ বা সম্পূর্ণ স্ট্রিং খুঁজে বের করে আপ ব্যবহার করা হয়েছে। সুতরাং একটি অনিচ্ছুক কোয়ান্টিফায়ার সংক্ষিপ্ত থেকে দীর্ঘতম পর্যন্ত সম্ভাব্য ম্যাচগুলি পরীক্ষা করে।

  • কোনও প্রবক্তা কোয়ান্টিফায়ার হ'ল প্রথম প্রয়াসে লোভী কোয়ান্টিফায়ারের মতো: এটি ইঞ্জিনটিকে পুরো স্ট্রিংটি পরীক্ষা করে শুরু করতে বলে। পার্থক্যটি হ'ল এটি যদি কাজ না করে তবে অধিকারী কোয়ান্টিফায়ার রিপোর্ট করে যে ম্যাচটি ঠিক তখনই ব্যর্থ হয়েছিল there ইঞ্জিনটি দেখানো স্ট্রিংয়ের অংশটি পরিবর্তন করে না এবং এটি আর কোনও চেষ্টা করে না।

এই কারণেই দখলযুক্ত কোয়ান্টিফায়ার ম্যাচটি আপনার উদাহরণে ব্যর্থ হয়: .*+পুরো স্ট্রিংয়ের সাথে এটি মেলে যা পুরোপুরি মিলিত হয়, তবে ইঞ্জিন তার fooপরে অতিরিক্ত অক্ষর সন্ধান করে - তবে অবশ্যই এটি তাদের খুঁজে পায় না কারণ আপনি স্ট্রিং শেষে ইতিমধ্যে। যদি এটি একটি লোভী কোয়ান্টিফায়ার হয় তবে এটি ব্যাকট্র্যাক হবে এবং .*পরের থেকে শেষের অক্ষর পর্যন্ত একমাত্র মিলটি তৈরি করার চেষ্টা করবে , তারপরে তৃতীয় থেকে শেষ চরিত্র পর্যন্ত, তারপর চতুর্থ থেকে শেষ চরিত্র পর্যন্ত, যা সফল হয় কারণ কেবল তখনই স্ট্রিংয়ের আগের অংশটি "খাওয়া" থাকার fooপরে একটি বাম আছে .*


1
এটি একটি দুর্দান্ত উত্স। আমি রাষ্ট্রের যন্ত্র ডায়াগ্রাম পছন্দ করি। :)
রেইজেক্স রুকি

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

@ ডেভিড জাস্লাভস্কি: ভালো ব্যাখ্যা। "একটি লোভী কোয়ানটিফায়ার ইঞ্জিনটিকে সম্পূর্ণ স্ট্রিং (বা কমপক্ষে, এর সবগুলি যা ইতিমধ্যে নিয়মিত অভিব্যক্তির আগের অংশগুলির সাথে মিলেছে না) দিয়ে শুরু করতে বলে" তে বন্ধনীগুলিতে আপনার মন্তব্যগুলি গুরুত্বপূর্ণ। তারা অনিচ্ছুক এবং অধিক পরিমাণে অধিকারী করার জন্যও আবেদন করে। এটি যখন আপনার উদাহরণের ধরণগুলি ("। * Foo"; "। *? Foo"; এবং "। * + Foo") থেকে "" foo। * ";" Foo। * থেকে পরিবর্তন করেন তখন তার সাথে আপনার ব্যাখ্যাটি সামঞ্জস্য করে তোলে? " "; এবং" ফু। * + ")।
জন বেন্টলে

আসলে, xfooxxxxxxfoo মেলে regular নিয়মিত অভিব্যক্তির স্বাভাবিক (কম্পিউটার বিজ্ঞানের অর্থ) oo এনএফএ এমন একটি রাজ্য হবে যেখানে এটি যে কোনও চরিত্রের সাথেই ছড়িয়ে পড়ে এবং তারপরে এটি ফুঁসে উঠতে পারে। ডিএফএ হ'ল এনএফএ-এর একটি সরল অনুবাদ translation এটি 8 টি রাজ্যে করা যেতে পারে।
user4951

@ জিমথিও হ্যাঁ, কারণ এটি কোনও অধিকারী পরিমাণ নেই।
ডেভিড জেড

12

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

লোভী - লোভী কোয়ান্টিফায়ার এবং পুরো রেজেক্সের সাথে যতটা সম্ভব ম্যাচ করুন। কোনও মিল না থাকলে লোভী কোয়ান্টিফায়ারকে ব্যাকট্র্যাক করুন।

ইনপুট: STRING xfooxxxxxxfoo
Regex: । * Foo বিন্যাস

উপরের রেজেক্সের দুটি অংশ রয়েছে:
(i) '। *' এবং
(ii) 'foo'

নীচের প্রতিটি পদক্ষেপের দুটি অংশ বিশ্লেষণ করবে। 'পাস' বা 'ব্যর্থ' ম্যাচের জন্য অতিরিক্ত মন্তব্যগুলি ধনুর্বন্ধনীগুলির মধ্যে ব্যাখ্যা করা হয়েছে।

পদক্ষেপ 1:
(i)। * = Xfooxxxxxxfoo - PASS ('। *' একটি লোভী কোয়ান্টিফায়ার এবং পুরো ইনপুট স্ট্রিংটি ব্যবহার করবে)
(ii) foo = 13 এর সূচকের পরে কোনও অক্ষর মেলে না - ব্যর্থ
ম্যাচ ব্যর্থ হয়।

পদক্ষেপ 2:
(i)। * = Xfooxxxxxxfo - PASS (লোভী কোয়ান্টিফায়ার উপর ব্যাকট্র্যাকিং '। *')
(Ii) foo = o - ব্যর্থ
ম্যাচ ব্যর্থ হয়েছে।

ধাপ 3:
। (ঝ) * = xfooxxxxxxf - পাস ( '। *' Backtracking লোভী কোয়ান্টিফায়ার দিকে)
(২) foo বিন্যাস = ওও - ব্যর্থ
ম্যাচ ব্যর্থ হয়েছে।

পদক্ষেপ 4:
(i)। * = Xfooxxxxxx - পাস (লোভী কোয়ান্টিফায়ার উপর ব্যাকট্র্যাকিং '। *')
(Ii) foo = foo - পাস
রিপোর্ট ম্যাচ

ফলাফল: 1 টি ম্যাচ (এসএস)
আমি "xfooxxxxxxfoo" পাঠ্যটি সূচক 0 থেকে শুরু করে 13 সূচীতে শেষ হতে দেখলাম।

অনিচ্ছুক - অনিচ্ছুক কোয়ান্টিফায়ারের সাথে যথাসম্ভব সামান্য ম্যাচ করুন এবং পুরো রেজেক্সটি মেলে। যদি কোনও মিল না থাকে তবে অনিচ্ছুক পরিমাণকে অক্ষর যুক্ত করুন characters

ইনপুট: STRING xfooxxxxxxfoo
Regex: ।? * Foo বিন্যাস

উপরের রেজেক্সের দুটি অংশ রয়েছে:
(i) '। *?' এবং
(ii) 'ফু'

পদক্ষেপ 1:।
*? = '' (ফাঁকা) - Pass (যতটা সম্ভব ম্যাচ সামান্য অনিচ্ছুক কোয়ান্টিফায়ার করতে '।। *'। ইনডেক্স 0 থাকার '' একটি ম্যাচ হয়)
- fail (সেল 0,1,2 - অর্থাৎ মধ্যে সূচক foo বিন্যাস = xfo 0 এবং 3)
ম্যাচ ব্যর্থ হয়েছে।

পদক্ষেপ 2:।
*? = x - পাস (অনিচ্ছুক কোয়ান্টিফায়ারগুলিতে অক্ষর যুক্ত করুন '। *?'। সেল 'এক্স' থাকা একটি ম্যাচ))
foo = foo - পাস
রিপোর্ট ম্যাচ

পদক্ষেপ 3:।
*? = '' (ফাঁকা) - Pass (যতটা সম্ভব ম্যাচ সামান্য অনিচ্ছুক কোয়ান্টিফায়ার করতে '।? *'। ইনডেক্স 4 থাকার '' একটি ম্যাচ হয়।)
Foo বিন্যাস = XXX - fail (সেল 4,5,6 - অর্থাৎ মধ্যে সূচক 4 এবং 7)
ম্যাচ ব্যর্থ হয়েছে।

পদক্ষেপ 4:।
*? = এক্স - Pass (অনিচ্ছুক কোয়ান্টিফায়ার অক্ষর যোগ সেল 4. '*।'।)
Foo বিন্যাস = XXX - fail (সেল 5,6,7 - অর্থাৎ সূচক 5 এবং 8 এর মধ্যে)
ম্যাচ ব্যর্থ হয়েছে।

পদক্ষেপ 5:।
*? = Xx - Pass (অনিচ্ছুক কোয়ান্টিফায়ার অক্ষর যোগ 5. পুরনো 4 সেল '*?।'।)
Foo বিন্যাস = XXX - fail (সেল 6,7,8 - অর্থাৎ সূচক 6 এবং 9 এর মধ্যে)
ম্যাচ ব্যর্থ হয়েছে।

পদক্ষেপ 6:।
*? = XXX - Pass (অনিচ্ছুক কোয়ান্টিফায়ার অক্ষর যোগ 6. পুরনো 4 সেল '*?।'।)
Foo বিন্যাস = XXX - fail (সেল 7,8,9 - অর্থাৎ সূচক 7 এবং 10 এর মধ্যে)
ম্যাচ ব্যর্থ হয়েছে।

পদক্ষেপ 7:।
*? = হাতের - Pass (7. পুরনো অনিচ্ছুক কোয়ান্টিফায়ার অক্ষর যোগ সেল 4 '*।?'।)
Foo বিন্যাস = xxf - fail (সেল 8,9,10 - অর্থাৎ 8 ও 11 মধ্যে INDEX)
ম্যাচ ব্যর্থ হয়েছে।

পদক্ষেপ 8:।
*? = XXXXX - Pass (8. পুরনো অনিচ্ছুক কোয়ান্টিফায়ার অক্ষর যোগ সেল 4 '*।?'।)
Foo বিন্যাস = xfo - fail (সেল 9,10,11 - অর্থাৎ সূচক 9 ও 12-এর মধ্যে)
ম্যাচ ব্যর্থ হয়েছে।

পদক্ষেপ 9:।
*? = Xxxxxx - Pass (অনিচ্ছুক কোয়ান্টিফায়ার অক্ষর যোগ 9. পুরনো সেল 4 '*।?'।)
Foo বিন্যাস = foo বিন্যাস - Pass (সেল 10,11,12 - 10 এবং 13 মধ্যে অর্থাত INDEX)
প্রতিবেদন নিয়ে খেলা

পদক্ষেপ 10:।
*? = '' (ফাঁকা) - পাস (অনিচ্ছুক কোয়ান্টিফায়ারের সাথে যতটা সম্ভব ম্যাচ ''। *? '। সূচি 13 ফাঁকা আছে))
foo = কোনও চরিত্রের মিল নেই - FAIL (মেলানোর জন্য সূচী 13 এর পরে কিছুই নেই)
ম্যাচ ব্যর্থ হয়েছে.

ফলাফল: 2 টি ম্যাচ (এসএস)
আমি "xfoo" পাঠ্যটি সূচক 0 থেকে শুরু করে সূচক 4 এ সমাপ্ত হয়ে
পেয়েছি x

প্যাসেসিভ - অধিক পরিমাণে অধিক পরিমাণে মিল করুন এবং পুরো রেজেক্সটি মিলিয়ে নিন match ব্যাকট্র্যাক করবেন না।

ইনপুট: STRING xfooxxxxxxfoo
Regex: । * + + Foo বিন্যাস

উপরের রেজেক্সের দুটি অংশ রয়েছে: '। * +' এবং 'ফু'।

ধাপ 1:
। * + + = Xfooxxxxxxfoo - পাস ( '। *' ম্যাচ সম্বন্ধসূচক কোয়ান্টিফায়ার করতে যতটা সম্ভব)
foo বিন্যাস থে চরিত্র মেলে বাম - fail (কিছুই সূচক 13 পরে মেলে)
ম্যাচ ব্যর্থ হয়েছে।

দ্রষ্টব্য: ব্যাকট্রাকিং অনুমোদিত নয়।

ফলাফল: 0 ম্যাচ (এসএস)


1

লোভী: "চরিত্রগুলির দীর্ঘতম সম্ভাব্য ক্রমটি মেলান"

অনিচ্ছুক: "অক্ষরের সংক্ষিপ্ততম অনুক্রমের সাথে মেলে"

প্যাসেসিভ: এটি কিছুটা অদ্ভুত কারণ এটি (লোভী এবং অনিচ্ছার বিপরীতে) পুরো রেজেক্সের জন্য কোনও মিল খুঁজে পাওয়ার চেষ্টা করে না।

যাইহোক: কোনও রেইজেক্স প্যাটার্ন ম্যাথার বাস্তবায়ন কখনই ব্যাকট্র্যাকিং ব্যবহার করবে না। সমস্ত বাস্তব জীবনের প্যাটার্ন ম্যাচার অত্যন্ত দ্রুত - নিয়মিত প্রকাশের জটিলতার চেয়ে প্রায় স্বতন্ত্র!


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

0

লোভী পরিমাপের মধ্যে একটি পুনরাবৃত্তি চলাকালীন স্ট্রিংয়ের বাকী সমস্ত অবৈধ অক্ষর ব্যবহার করে প্যাটার্ন ম্যাচিং জড়িত। অবৈধ অক্ষর সক্রিয় ক্রম শুরু হয় । প্রতিবার কোনও ম্যাচ না ঘটে, শেষে অক্ষরটি আলাদা করা হয় এবং চেকটি আবার করা হয়।

যখন কেবলমাত্র রেজেক্স প্যাটার্নের শীর্ষস্থানীয় শর্তগুলি সক্রিয় ক্রম দ্বারা সন্তুষ্ট হয়, তখন পৃথক অবস্থার বিপরীতে অবশিষ্ট শর্তগুলি বৈধ করার চেষ্টা করা হয়। যদি এই বৈধতা সফল হয়, তবে পৃথক পৃথকীকরণের সাথে মিলিত অক্ষরগুলি বৈধ হয়ে যায় এবং অবশিষ্ট মিলহীন অক্ষরগুলি অবৈধ থেকে যায় এবং পরবর্তী পুনরাবৃত্তিতে প্রক্রিয়াটি নতুনভাবে শুরু হলে ব্যবহৃত হবে।

চরিত্রগুলির প্রবাহটি সক্রিয় ক্রম থেকে পৃথক পৃথকীকরণে আসে। ফলস্বরূপ আচরণটি হ'ল মূল ক্রমটি যতটা সম্ভব একটি ম্যাচে অন্তর্ভুক্ত।

চরিত্রের প্রবাহ বিপরীত ব্যতীত অনিচ্ছুক পরিমাণকে বেশিরভাগ লোভী যোগ্যতার মতোই - অর্থাৎ, তারা পৃথকীকরণে শুরু হয় এবং সক্রিয় ক্রমের মধ্যে প্রবাহিত হয় । ফলস্বরূপ আচরণটি হ'ল মূল ক্রমটি যতটা সম্ভব একটি ম্যাচে অন্তর্ভুক্ত থাকে।

প্যাসেসিভ কোয়ান্টিফিকেশনটিতে কোয়ারানটাইন থাকে না এবং এটি একটি নির্দিষ্ট সক্রিয় ক্রম অনুসারে সবকিছু অন্তর্ভুক্ত করে ।

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