কীভাবে বা কেন `। *? Using ব্যবহার করা`। * * `এর চেয়ে ভাল?


9

আমি সুপার ইউজারে এই প্রশ্নের উত্তর দিয়েছি যা কোনও আউটপুট গ্রেপ করার সময় ব্যবহৃত নিয়মিত প্রকাশের সাথে সম্পর্কিত related

আমি যে উত্তরটি দিয়েছিলাম তা হ'ল:

 tail -f log | grep "some_string.*some_string"

এবং তারপরে, আমার উত্তর সম্পর্কে তিনটি মন্তব্যে @ Bob এটি লিখেছেন:

.*লোভী এবং আপনি চান তার চেয়ে বেশি ক্যাপচার করতে পারে। .*?সাধারণত ভাল হয়।

তারপর এই,

?একটি পরিবর্তক হয় *, এটা লোভী ডিফল্ট পরিবর্তে অলস করে। ধরে নিচ্ছি পিসিআরই।

আমি গুগল করেছিলাম PCRE, তবে আমার উত্তরে এর তাত্পর্য কী পাওয়া গেল না?

এবং অবশেষে এটি,

আমার এটিও উল্লেখ করা উচিত যে এটি রেজেক্স (ডিফল্টরূপে POSIX রেজেক্স করছে গ্রেপ), শেল গ্লোব নয়।

আমি কেবল জানি রেজেক্স কী এবং গ্রেপ কমান্ডে এটির খুব বেসিক ব্যবহার। সুতরাং, আমি এই 3 টির মধ্যে একটিও মন্তব্য পেতে পারি নি এবং আমার মনে এই প্রশ্নগুলি রয়েছে:

  • .*?বনাম ব্যবহারের পার্থক্য কী .*?
  • কোনটি ভাল এবং কোন পরিস্থিতিতে? উদাহরণ প্রদান করুন।

এছাড়াও মন্তব্যগুলি বুঝতে সহায়ক হবে, যদি কেউ পারে


আপডেট: প্রশ্নের উত্তর হিসাবে কীভাবে শেল গ্লোবগুলি থেকে রেগেক্স আলাদা? @ কুসালানন্দ তার মন্তব্যে এই লিঙ্কটি সরবরাহ করেছেন।

দ্রষ্টব্য: যদি প্রয়োজন হয়, অনুগ্রহ করে রেফারেন্স দেওয়ার জন্য উত্তর দেওয়ার আগে এই প্রশ্নের আমার উত্তরটি পড়ুন ।


এটি দুটি খুব আলাদা প্রশ্ন। প্রথম প্রশ্নের উত্তর ইউনিক্স.স্ট্যাকেক্সেঞ্জার্ভিউ / প্রশ্ন / 5795957/২ দ্বারা দেওয়া হয়েছে যখন দ্বিতীয় প্রশ্নটি প্যাটার্নের প্রয়োগের উপর নির্ভরশীল (এটি সব পরিস্থিতিতে "আরও ভাল" বলা যায় না)।
কুসালানন্দ

আপনি এই প্রশ্নটি কেবল বনাম ইস্যু সম্পর্কে হতে সম্পাদনা করতে পারেন । "নিয়মিত এক্সপ্রেশন এবং শেল গ্লোবগুলির মধ্যে পার্থক্য" প্রশ্নটি ইতিমধ্যে এই সাইটে মোকাবেলা করা হয়েছে। .*.*?
কুসালানন্দ

উত্তর:


7

অশোক ইতিমধ্যে.* এবং এর মধ্যে পার্থক্যটি নির্দেশ করেছেন.*? , তাই আমি কেবল কিছু অতিরিক্ত তথ্য সরবরাহ করব।

grep (ধরে নিলেন জিএনইউ সংস্করণ) স্ট্রিংগুলির সাথে মেলে 4 টি উপায় সমর্থন করে:

  • স্থির স্ট্রিং
  • বেসিক নিয়মিত এক্সপ্রেশন (বিআরই)
  • বর্ধিত নিয়মিত এক্সপ্রেশন (ERE)
  • পার্ল-সামঞ্জস্যপূর্ণ নিয়মিত এক্সপ্রেশন (পিসিআরই)

grep ডিফল্টরূপে BRE ব্যবহার করে।

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

এটি বলার অপেক্ষা রাখে না যে BRE বা ERE কেউই অলসতার সমর্থন করে না :

একাধিক সংলগ্ন সদৃশ চিহ্নগুলির আচরণ ('+', '*', '?', এবং অন্তর) অনির্ধারিত ফলাফল দেয়।

সুতরাং আপনি যদি সেই বৈশিষ্ট্যটি ব্যবহার করতে চান তবে আপনার পরিবর্তে পিসিআরই ব্যবহার করতে হবে:

# BRE greedy
$ grep -o 'c.*s' <<< 'can cats eat plants?'
can cats eat plants

# BRE lazy
$ grep -o 'c.*\?s' <<< 'can cats eat plants?'
can cats eat plants

# ERE greedy
$ grep -E -o 'c.*s' <<< 'can cats eat plants?'
can cats eat plants

# ERE lazy
$ grep -E -o 'c.*?s' <<< 'can cats eat plants?'
can cats eat plants

# PCRE greedy
$ grep -P -o 'c.*s' <<< 'can cats eat plants?'
can cats eat plants

# PCRE lazy
$ grep -P -o 'c.*?s' <<< 'can cats eat plants?'
can cats

সম্পাদনা 1

.*বনাম সম্পর্কে একটু ব্যাখ্যা করতে পারেন .*??

  • .*সম্ভব "দীর্ঘতম" 1 প্যাটার্নের সাথে মেলে ব্যবহার করা হয় ।

  • .*?সম্ভব "সংক্ষিপ্ততম" 1 প্যাটার্নটি মেলাতে ব্যবহৃত হয় ।

আমার অভিজ্ঞতায়, সর্বাধিক ওয়ান্টেড আচরণটি সাধারণত দ্বিতীয়টি।

উদাহরণস্বরূপ, ধরা যাক আমাদের নিম্নলিখিত স্ট্রিং রয়েছে এবং আমরা কেবল এইচটিএমএল ট্যাগ 2 এর সাথে মেলে দেখতে চাই , তাদের মধ্যে থাকা সামগ্রীটি নয়:

<title>My webpage title</title>

এখন .*বনাম তুলনা করুন .*?:

# Greedy
$ grep -P -o '<.*>' <<< '<title>My webpage title</title>'
<title>My webpage title</title>

# Lazy
$ grep -P -o '<.*?>' <<< '<title>My webpage title</title>'
<title>
</title>

১. "সবচেয়ে দীর্ঘ" এবং "সংক্ষিপ্ততম" অর্থ একটি রেজেক্স প্রসঙ্গে কিছুটা জটিল, যেমনটি কুসালানন্দ উল্লেখ করেছিলেন । আরও তথ্যের জন্য অফিসিয়াল ডকুমেন্টেশন দেখুন।
2. এটা Regex সঙ্গে পার্স এইচটিএমএল করা বাঞ্ছনীয় নয় । এটি শিক্ষামূলক উদ্দেশ্যে কেবল উদাহরণ, এটি উত্পাদনতে ব্যবহার করবেন না।


.*বনাম সম্পর্কে একটু ব্যাখ্যা করতে পারেন .*??
C0deaaalalus

@ C0deDaedalus আপডেট হয়েছে।
nxnev

9

ধরুন আমি এর মতো স্ট্রিং নিলাম:

can cats eat plants?

লোভী ব্যবহার করা c.*sসম্পূর্ণ স্ট্রিংয়ের সাথে মিলবে কারণ এটি শুরু হয় cএবং শেষ হয় s, লোভী অপারেটর হয়ে এটি চূড়ান্ত উপস্থিতি অবধি মিলতে থাকে।

যেখানে অলস ব্যবহার করা c.*?sকেবল তার প্রথম উপস্থিতি sঅর্থাৎ স্ট্রিং না পাওয়া পর্যন্ত মিলবে can cats

উপরের উদাহরণ থেকে আপনি এটি সংগ্রহ করতে সক্ষম হতে পারেন:

"লোভী" এর অর্থ দীর্ঘতম সম্ভাব্য স্ট্রিংয়ের সাথে মিল। "অলস" এর অর্থ সংক্ষিপ্ততম স্ট্রিংয়ের সাথে মিল। একটি যোগ করার পদ্ধতি ?মত একটি কোয়ান্টিফায়ার করতে *, +, ?, অথবা {n,m}তোলে অলস।


1
"সবচেয়ে সংক্ষিপ্ত সম্ভব" হবে cats, সুতরাং এটি সেই অর্থে কঠোরভাবে "সংক্ষিপ্ততম" প্রয়োগ করছে না।
কুসালানন্দ

2
@ কুসালানন্দ সত্য, দৃ sense়ভাবে সেই অর্থে নয় তবে "সংক্ষিপ্ততম সম্ভব" এর অর্থ সি এবং এস উভয়ের প্রথম সংঘর্ষের মধ্যে।
অশোক অরোরা 10

1

একটি স্ট্রিং বিভিন্ন উপায়ে মেলা যায় (সাধারণ থেকে আরও জটিল পর্যন্ত):

  1. স্ট্যাটিক স্ট্রিং হিসাবে (ধরুন ভার = 'হ্যালো ওয়ার্ল্ড!'):

    [ "$var" = "Hello World!" ] && echo yes
    echo "$var" | grep -F "Hello"
    grep -F "Hello" <<<"$var"

  2. গ্লোব হিসাবে:

    echo ./* # পিডাব্লুডিতে সমস্ত ফাইলের তালিকা ।
    case $var in (*Worl*) echo yes;; (*) echo no;; esac
    [[ "$var" == *"Worl"* ]] && echo yes

    বেসিক এবং বর্ধিত গ্লোব রয়েছে। caseউদাহরণস্বরূপ মৌলিক globs ব্যবহার করুন। বাশ [[উদাহরণটি বর্ধিত গ্লোব ব্যবহার করে। প্রথম ফাইলের ম্যাচটি বেসের মধ্যে সেট করার মতো কিছু শেলের উপর বেসিক বা বাড়ানো হতে পারে extglob। এই ক্ষেত্রে উভয়ই অভিন্ন ident গ্রেপ গ্লোব ব্যবহার করতে পারেনি।

    একটি তারকাচিহ্ন উল্লিখিত glob মানে একটি একটি তারকা চেয়ে ভিন্ন কিছু Regex :

    * matches any number (including none) ofকোনও অক্ষর পূর্ববর্তী উপাদান
    * matches any number (including none) of the

  3. একটি প্রাথমিক নিয়মিত প্রকাশ (বিআরই) হিসাবে:

    echo "$var" | sed 's/W.*d//' # মুদ্রণ: হ্যালো!
    grep -o 'W.*d' <<<"$var" # প্রিন্ট ওয়ার্ল্ড!

    (বেসিক) শেল বা অজকের কোনও বিআরই নেই।

  4. বর্ধিত নিয়মিত এক্সপ্রেশন (ERE):

    [[ "$var" =~ (H.*l) ]] # মিল: হ্যালো পৃথিবী
    echo "$var" | sed -E 's/(d|o)//g' # মুদ্রণ: জাহান্নামের Wrl!
    awk '/W.*d/{print $1}' <<<"$var" # মুদ্রণ: হ্যালো
    grep -oE 'H.*l' <<<"$var" # মুদ্রণ: হ্যালো পৃথিবী

  5. পার্ল সামঞ্জস্যপূর্ণ নিয়মিত এক্সপ্রেশন:

    grep -oP 'H.*?l # মুদ্রণ: হেল

কেবলমাত্র একটি পিসিআরই-তে একটি *?নির্দিষ্ট সিনট্যাক্স অর্থ has
এটি অরক্ষাকে অলস করে তোলে (লোভী): লোভের পরিবর্তে অলসতা

$ grep -oP 'e.*l' <<<"$var"
ello Worl

$ grep -oP 'e.*?l' <<<"$var"
el

এটি হ'ল আইসবার্গের টিপ, লোভী, অলস এবং নীতিবোধ বা দখলদার রয়েছেলুকোহেড এবং লুকবিহাইন্ড এছাড়াও রয়েছে তবে সেগুলি নক্ষত্রের উপর প্রয়োগ হয় না *

অ-লোভী রেজেক্সের মতো একই প্রভাব পেতে বিকল্প রয়েছে:

$ grep -o 'e[^o]*o' <<<"$var"
ello

ধারণাটি খুব সহজ: কোনও বিন্দু ব্যবহার করবেন না ., পরবর্তী অক্ষরটি মেলাতে অস্বীকার করুন [^o]। একটি ওয়েব ট্যাগ সহ:

$ grep -o '<[^>]*>' <<<'<script type="text/javascript">document.write(5 + 6);</script>'
<script type="text/javascript">
</script>

উপরের সমস্তগুলি @ Bob 3 টি মন্তব্য সম্পূর্ণরূপে পরিষ্কার করা উচিত। paraphrasing:

  • ক। * একটি সাধারণ রেজেেক্স, গ্লোব নয়।
  • কেবলমাত্র একটি রেজেক্স পিসিআরই সামঞ্জস্যপূর্ণ হতে পারে।
  • পিসিআরই তে: ক? * কোয়ানটিফায়ার পরিবর্তন করুন। .*লোভী .*?হয় না।

প্রশ্নাবলি

  • ব্যবহারের ক্ষেত্রে পার্থক্য কী। ? বনাম। ?

    • .*?কেবল পিসিআরই সিন্টেক্সে বৈধ।
    • .*আরও পোর্টেবল।
    • অ-লোভী মিলের মতো একই প্রভাব বিন্দুর পরিবর্তে একটি অবহেলিত চরিত্রের পরিসর দিয়ে করা যেতে পারে: [^a]*
  • কোনটি ভাল এবং কোন পরিস্থিতিতে? উদাহরণ প্রদান করুন।
    উত্তম? এটি লক্ষ্য উপর নির্ভর করে। এর চেয়ে ভাল আর নেই, প্রতিটি বিভিন্ন উদ্দেশ্যে কার্যকর। আমি উপরে বেশ কয়েকটি উদাহরণ সরবরাহ করেছি। আপনার কি আরো প্রয়োজন?

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