নিয়মিত প্রকাশের প্রসঙ্গে 'অলস' এবং 'লোভী' বলতে কী বোঝায়?


উত্তর:


643

লোভী যতটা সম্ভব গ্রাস করবে। Http://www.regular-expressions.info/repeat.html থেকে আমরা এইচটিএমএল ট্যাগগুলির সাথে মেলে চেষ্টা করার উদাহরণ দেখি <.+>। ধরুন আপনার নিম্নলিখিতগুলি রয়েছে:

<em>Hello World</em>

তুমি ভাবছ পারে যে <.+>( .মানে কোনো অ newline অক্ষর এবং +মানে এক বা একাধিক ) শুধুমাত্র মেলে দিবে <em>এবং </em>যখন বাস্তবে এটা খুবই লোভী হবে, এবং প্রথম থেকে যেতে <শেষ >। এর অর্থ এটি <em>Hello World</em>আপনি যা চেয়েছিলেন তার পরিবর্তে এটি মিলবে ।

এটি অলস ( <.+?>) তৈরি করা এটিকে প্রতিরোধ করবে। এর ?পরে যুক্ত করে +, আমরা এটিকে যতবার সম্ভব কয়েকবার পুনরাবৃত্তি করতে বলি , সুতরাং এটি সর্বপ্রথম >আসে, যেখানে আমরা ম্যাচটি বন্ধ করতে চাই।

আমি আপনাকে RegExr ডাউনলোড করার জন্য উত্সাহিত করব , একটি দুর্দান্ত সরঞ্জাম যা আপনাকে নিয়মিত অভিব্যক্তিগুলি অন্বেষণে সহায়তা করবে - আমি এটি সর্বদা ব্যবহার করি।


2
সুতরাং আপনি যদি লোভী ব্যবহার করেন তবে আপনার কি 3 (1 উপাদান + 2 ট্যাগ) ম্যাচ হবে বা মাত্র 1 ম্যাচ (1 উপাদান)?
আজিজি

10
প্রথম < থেকে শুরু করে শেষটি > দিয়ে শুরু হয়ে এটি কেবল 1 বার মিলবে ।
সাম্পসন

3
তবে এটিকে অলস করা দু'বারের সাথে মিলবে, যা আমাদের উদ্বোধনী এবং সমাপনী উভয় ট্যাগ দেয়, পাঠ্যটিকে মাঝখানে উপেক্ষা করে (যেহেতু এটি প্রকাশের সাথে খাপ খায় না)।
সাম্পসন

আমি সর্বদা অন্য দুর্দান্ত সরঞ্জামটি ব্যবহার করি: debuggex.com এর এটিতে "স্ট্যাক ওভারফ্লোতে এম্বেড" ফাংশন রয়েছে।
রন ভ্যান ডের হাইজডেন

8
এটি যুক্ত করার জন্য একটি লোভী উপায় রয়েছে কেবল তা যুক্ত করার জন্য: <[^>]+> regex101.com/r/lW0cY6/1
এলানবুকানান

301

'লোভী' মানে দীর্ঘতম সম্ভাব্য স্ট্রিং ম্যাচ।

'অলস' মানে ম্যাচটি স্বল্পতম সম্ভাব্য স্ট্রিং।

উদাহরণস্বরূপ, লোভী h.+lম্যাচ 'hell'মধ্যে 'hello'কিন্তু অলস h.+?lম্যাচ 'hel'


96
উজ্জ্বল, শর্তটি সন্তুষ্ট হওয়ার সাথে সাথে অলস বন্ধ হয়ে যাবে, তবে লোভী মানে এই শর্তটি কেবলমাত্র আমি আর সন্তুষ্ট না হলে কেবল এটি বন্ধ হয়ে যাবে?
অ্যান্ড্রু এস

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

3
@ অ্যান্ড্রুস উদাহরণে ডাবল এলএল দ্বারা বিভ্রান্ত হবেন না। এটি বরং অলস সংক্ষিপ্ততম সম্ভাব্য স্ট্রিংয়ের সাথে মেলে তবে লোভী দীর্ঘতমের সাথে মিলবে। লোলুপ h.+lম্যাচ 'helol'মধ্যে 'helolo'কিন্তু অলস h.+?lম্যাচ 'hel'
v.sashenko

3
@ ফ্লাইটিংরক: নং x?অর্থ optionচ্ছিক xতবে +?এটি একটি ভিন্ন বাক্য গঠন। এর অর্থ হ'ল আপনি মিলেছে এমন কিছু সন্ধান করার পরে দেখা বন্ধ করুন - অলস মিল matching
slebetman

1
@ ফ্লাইটিংরক: আপনি কীভাবে বিভিন্ন সিনট্যাক্সকে আলাদা করতে পারেন, সহজ: ?অর্থ meansচ্ছিক এবং +?মানে অলস la সুতরাং \+?অর্থ +alচ্ছিক।
slebetman

113
+-------------------+-----------------+------------------------------+
| Greedy quantifier | Lazy quantifier |        Description           |
+-------------------+-----------------+------------------------------+
| *                 | *?              | Star Quantifier: 0 or more   |
| +                 | +?              | Plus Quantifier: 1 or more   |
| ?                 | ??              | Optional Quantifier: 0 or 1  |
| {n}               | {n}?            | Quantifier: exactly n        |
| {n,}              | {n,}?           | Quantifier: n or more        |
| {n,m}             | {n,m}?          | Quantifier: between n and m  |
+-------------------+-----------------+------------------------------+

যুক্ত কর একটি ? এটি নির্দ্বিধায় অর্থাৎ অলস করতে একটি কোয়ান্টিফায়ারকে।

উদাহরণ:
পরীক্ষা: STRING Stackoverflow
লোভী REG অভিব্যক্তি : s.*oআউটপুট: stackoverflo W
অলস REG অভিব্যক্তি : s.*?oআউটপুট: stacko verflow


2
এটি না ?? সমতুল্য ? । একইভাবে, {n} নয়? সমান {n}
945

5
@ ব্রেকিংবেঞ্জামিন: না ?? এর সমতুল্য নয়?, যখন এটি 0 বা 1 ঘটনাটি ফেরত দেওয়ার পছন্দ আছে, তখন 0 (অলস) বিকল্পটি বেছে নেবে। পার্থক্যটি দেখতে, তুলনা re.match('(f)?(.*)', 'food').groups()করুন re.match('(f)??(.*)', 'food').groups()। পরবর্তীকালে, (f)??শীর্ষস্থানীয় 'চ' এর সাথে মেলে না যদিও তা পারে। সুতরাং 'চ' দ্বিতীয় '। *' ক্যাপচার গ্রুপের সাথে মিলবে। আমি নিশ্চিত আপনি '{n' 'দিয়ে একটি উদাহরণ তৈরি করতে পারবেন? খুব। স্বীকারোক্তিজনকভাবে এই দুটি খুব কমই ব্যবহৃত হয়।
smci

55

লোভী মানে আপনার অভিব্যক্তি যতটা সম্ভব বৃহত্তর একটি দলের সাথে মিলবে, অলস অর্থ এটি সম্ভব সবচেয়ে ছোট দলের সাথে মিলবে। এই স্ট্রিংয়ের জন্য:

abcdefghijklmc

এবং এই অভিব্যক্তি:

a.*c

একটি লোভী ম্যাচ পুরো স্ট্রিংয়ের সাথে মিলবে এবং একটি অলস ম্যাচটি কেবল প্রথমটির সাথে মিলবে abc


16

আমি যতদূর জানি, বেশিরভাগ রেজেক্স ইঞ্জিন ডিফল্টরূপে লোভী। কোয়ান্টিফায়ার শেষে একটি প্রশ্ন চিহ্ন যুক্ত করুন অলস ম্যাচ সক্ষম করে।

যেমনটি @ আন্ড্রে এস মন্তব্যে উল্লেখ করেছেন।

  • লোভী: শর্তটি সন্তুষ্ট না হওয়া পর্যন্ত অনুসন্ধান চালিয়ে যান।
  • অলস: শর্তটি সন্তুষ্ট হলে অনুসন্ধান বন্ধ করুন।

কী লোভী এবং কোনটি অলস, তার জন্য নীচের উদাহরণটি দেখুন।

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
    public static void main(String args[]){
        String money = "100000000999";
        String greedyRegex = "100(0*)";
        Pattern pattern = Pattern.compile(greedyRegex);
        Matcher matcher = pattern.matcher(money);
        while(matcher.find()){
            System.out.println("I'm greeedy and I want " + matcher.group() + " dollars. This is the most I can get.");
        }

        String lazyRegex = "100(0*?)";
        pattern = Pattern.compile(lazyRegex);
        matcher = pattern.matcher(money);
        while(matcher.find()){
            System.out.println("I'm too lazy to get so much money, only " + matcher.group() + " dollars is enough for me");
        }
    }
}


ফলাফল হলো:

I'm greeedy and I want 100000000 dollars. This is the most I can get.

I'm too lazy to get so much money, only 100 dollars is enough for me

9

Www.regular-expressions.info থেকে নেওয়া

লোভতা : লোভী কোয়ান্টিফায়াররা প্রথমে টোকেনটিকে যতবার সম্ভব পুনরাবৃত্তি করার চেষ্টা করে এবং সামগ্রিক মিল খুঁজে পাওয়ার জন্য ধীরে ধীরে ইঞ্জিন ব্যাকট্র্যাক হিসাবে ম্যাচগুলি ছেড়ে দেয়।

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


6

নিয়মিত প্রকাশ থেকে

নিয়মিত প্রকাশের মানক কোয়ান্টিফায়ারগুলি লোভী, যার অর্থ তারা যথাসম্ভব মেলে, কেবলমাত্র রেগেক্সের বাকী অংশগুলির সাথে ম্যাচ করার জন্য প্রয়োজনীয় হিসাবে ফিরিয়ে দেয়।

একটি অলস কোয়ান্টিফায়ার ব্যবহার করে, এক্সপ্রেশনটি সর্বনিম্ন ম্যাচটি চেষ্টা করে।


4

লোভী মিলছে। নিয়মিত প্রকাশের ডিফল্ট আচরণ লোভী হতে হয়। এর অর্থ এটি যতক্ষণ সম্ভব একটি ছোট্ট অংশটি সিনট্যাক্টিকভাবে পর্যাপ্ত পর্যাপ্ত ছিল এমনকী কোনও প্যাটার্নের সাথে মিল না হওয়া পর্যন্ত এটি যথাসম্ভব উত্তোলনের চেষ্টা করে।

উদাহরণ:

import re
text = "<body>Regex Greedy Matching Example </body>"
re.findall('<.*>', text)
#> ['<body>Regex Greedy Matching Example </body>']

'>' এর প্রথম উপস্থিতি পর্যন্ত মিলের পরিবর্তে এটি পুরো স্ট্রিংটি বের করে। এটি হ'ল ডিফল্ট লোভী বা 'এটি সব নিয়ে যান' রেইগেক্সের আচরণ।

অন্যদিকে অলস মিলন 'যতটা সম্ভব সামান্য লাগে'। ?প্যাটার্নের শেষে একটি যুক্ত করে এটি প্রভাবিত হতে পারে ।

উদাহরণ:

re.findall('<.*?>', text)
#> ['<body>', '</body>']

আপনি যদি কেবল প্রথম ম্যাচটি পুনরুদ্ধার করতে চান তবে পরিবর্তে অনুসন্ধান পদ্ধতিটি ব্যবহার করুন।

re.search('<.*?>', text).group()
#> '<body>'

উত্স: পাইথন রেজেক্স উদাহরণ


3

লোভী এর অর্থ এটি আপনার প্যাটার্নটি গ্রাস করবে যতক্ষণ না তাদের মধ্যে কিছু না থাকে এবং এটি আর দেখতে পাবে না।

আপনার অনুরোধ করা প্রথম প্যাটার্নটির মুখোমুখি হওয়ার সাথে সাথে অলসতা থামবে।

একটি প্রায়শই উদাহরণ যা আমি প্রায়শই মুখোমুখি হই তা হ'ল \s*-\s*?একটি রেজেক্স([0-9]{2}\s*-\s*?[0-9]{7})

প্রথমটি \s*লোভী হিসাবে শ্রেণীবদ্ধ করা হয়েছে কারণ *এবং অঙ্কগুলি সংঘটিত হওয়ার পরে যতটা সম্ভব সাদা স্পেস দেখাবে এবং তারপরে একটি ড্যাশ চরিত্রের সন্ধান করবে "-"। দ্বিতীয়টি \s*?উপস্থিত হওয়ার কারণে যেখানে অলস, *?যার অর্থ এটি প্রথম সাদা স্থানের অক্ষরটি দেখবে এবং ঠিক সেখানে থামবে।


3

উদাহরণস্বরূপ সেরা দেখানো হয়েছে। স্ট্রিং। 192.168.1.1এবং একটি লোভী রেজেক্স \b.+\b আপনি মনে করতে পারেন এটি আপনাকে 1 ম অক্টেট দেবে তবে এটি পুরো স্ট্রিংয়ের সাথে মিল রয়েছে। কেন? কারণ। + লোভী এবং লোভী ম্যাচটি প্রতিটি চরিত্রের সাথে মিলে যায় 192.168.1.1যতক্ষণ না স্ট্রিংয়ের শেষে পৌঁছায়। এটি গুরুত্বপূর্ণ বিট! এখন এটি তৃতীয় টোকেন ( \b) এর সাথে কোনও মিল খুঁজে পাওয়া না পাওয়া অবধি একবারে একটি চরিত্রকে ব্যাকট্র্যাক করা শুরু করে ।

যদি স্ট্রিংটিতে 4 জিবি টেক্সট ফাইল এবং 192.168.1.1 শুরু হয় আপনি সহজেই দেখতে পেতেন কীভাবে এই ব্যাকট্র্যাকিংয়ের ফলে কোনও সমস্যার সৃষ্টি হবে।

একটি রেজেক্স অ লোভী করতে (অলস) আপনার লোভী অনুসন্ধানের পরে একটি প্রশ্ন চিহ্ন রাখুন যেমন

*?
??
+?

এখন যা ঘটে তা হ'ল টোকেন 2 ( +?) একটি মিল খুঁজে পায়, রেজেক্স একটি চরিত্রের সাথে এগিয়ে যায় এবং তারপরে \bটোকন 2 ( +?) এর পরিবর্তে পরবর্তী টোকেন ( ) চেষ্টা করে । সুতরাং এটি আদা সঙ্গে বজায় রাখা।


0

লোভী কোয়ান্টিফায়াররা আইআরএস / এটিওর মতো: তারা যতটা পারে ততটুকু নেয়:

যদি এটি সেখানে থাকে তবে তারা এসে এটি নিয়ে যাবে। তারা এগুলি সব নেবে:

উদাহরণস্বরূপ, আইআরএস এই রেজেক্সের সাথে মেলে: .*

$50,000 - আইআরএস সব নেবে। যারা লোভী .*{4}?এরস

উদাহরণের জন্য এখানে দেখুন: regexr.com/4t27f

অ-লোভী কোয়ান্টিফায়ার - তারা যতটা পারে সামান্য নেয়

অন্যদিকে, আমি যদি শুল্কের ফেরতের জন্য জিজ্ঞাসা করি, আইআরএস হঠাৎ অ-লোভী হয়ে যায় এবং তারা এই পরিমাণটি ব্যবহার করে:

(.{2}?)([0-9]*)এই অভিব্যক্তির বিপরীতে: $50,000প্রথম গ্রুপটি অ-অভাবী এবং কেবল মেলে $5- তাই আমি $5ফেরত পাব । বাকিগুলি চাচা স্যাম নষ্ট করে ব্যয় করতে নিয়ে গেছে।

এখানে দেখুন: অ-লোভী-উদাহরণ

কেন বিরক্ত হও?

আপনি যদি কোনও অভিব্যক্তির কিছু অংশের সাথে মেলে চেষ্টা করছেন তবে এটি গুরুত্বপূর্ণ হয়ে ওঠে। কখনও কখনও আপনি সব কিছু করতে চান না।


-3

নিম্নলিখিত আচরণ বোঝার চেষ্টা করুন:

    var input = "0014.2";

Regex r1 = new Regex("\\d+.{0,1}\\d+");
Regex r2 = new Regex("\\d*.{0,1}\\d*");

Console.WriteLine(r1.Match(input).Value); // "0014.2"
Console.WriteLine(r2.Match(input).Value); // "0014.2"

input = " 0014.2";

Console.WriteLine(r1.Match(input).Value); // "0014.2"
Console.WriteLine(r2.Match(input).Value); // " 0014"

input = "  0014.2";

Console.WriteLine(r1.Match(input).Value); // "0014.2"
Console.WriteLine(r2.Match(input).Value); // ""
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.