যখন একটি রেজিপ্সে গ্রুপ থাকে, তখন এর বিরুদ্ধে স্ট্রিংয়ের মিলের একাধিক উপায় থাকতে পারে: গোষ্ঠীগুলির সাথে রিজেক্সপগুলি অস্পষ্ট। উদাহরণস্বরূপ, regexp ^.*\([0-9][0-9]*\)$
এবং স্ট্রিং বিবেচনা করুন a12
। দুটি সম্ভাবনা রয়েছে:
a
বিপক্ষে .*
এবং 2
বিপক্ষে ম্যাচ [0-9]*
; 1
দ্বারা মেলানো হয় [0-9]
।
a1
বিপক্ষে ম্যাচ .*
এবং এর বিরুদ্ধে খালি স্ট্রিং [0-9]*
; 2
দ্বারা মেলানো হয় [0-9]
।
শেড, অন্য সমস্ত রেজিএক্সএক্স সরঞ্জামগুলির মতো, সবচেয়ে দীর্ঘতম ম্যাচের নিয়মটি প্রয়োগ করে: এটি প্রথমে যতটা সম্ভব তার স্ট্রিংয়ের সাথে প্রথম ভেরিয়েবল-দৈর্ঘ্যের অংশটি মেলানোর চেষ্টা করে। এটি যদি রেজিএক্সপি বাকি অংশের সাথে বাকী স্ট্রিংয়ের সাথে কোনও মিল খুঁজে পায়, ঠিক আছে। অন্যথায়, সেড প্রথম পরিবর্তনশীল-দৈর্ঘ্যের অংশের জন্য পরবর্তী দীর্ঘতম ম্যাচটি চেষ্টা করে এবং আবার চেষ্টা করে।
এখানে, সবচেয়ে দীর্ঘতম স্ট্রিংয়ের সাথে ম্যাচটি প্রথম a1
বিপক্ষে .*
, সুতরাং গ্রুপটি কেবল মিলছে 2
। আপনি যদি গোষ্ঠীটি শুরু করতে চান তবে কিছু রিজেক্সপ ইঞ্জিন আপনাকে .*
কম লোভী করতে দেয় তবে সেডের এমন বৈশিষ্ট্য নেই। সুতরাং আপনার কিছু অতিরিক্ত অ্যাঙ্কর দিয়ে অস্পষ্টতা সরিয়ে ফেলতে হবে । উল্লেখ করুন যে শীর্ষস্থানীয় অঙ্কটি দিয়ে .*
শেষ হতে পারে না, যাতে গোষ্ঠীর প্রথম সংখ্যাটি প্রথম সম্ভাব্য ম্যাচ হয়।
অঙ্কের গোষ্ঠীটি যদি লাইনের শুরুতে নাও পারে:
sed -n 's/^.*[^0-9]\([0-9][0-9]*\).*/\1/p'
যদি অঙ্কগুলির গোষ্ঠীটি লাইনের শুরুতে হতে পারে এবং আপনার সেড \?
অপারেটরটিকে partsচ্ছিক অংশগুলির জন্য সমর্থন করে :
sed -n 's/^\(.*[^0-9]\)\?\([0-9][0-9]*\).*/\1/p'
যদি সংখ্যার গোষ্ঠীটি লাইনের শুরুতে হতে পারে তবে স্ট্যান্ডার্ড রিজেক্সপ কনস্ট্রাক্টসের সাথে লেগে থাকে:
sed -n -e 's/^.*[^0-9]\([0-9][0-9]*\).*/\1/p' -e t -e 's/^\([0-9][0-9]*\).*/\1/p'
যাইহোক, এটি একই দীর্ঘতম দীর্ঘতম ম্যাচের নিয়ম যা [0-9]*
পরবর্তীকালের পরিবর্তে প্রথমটির পরে অঙ্কগুলির সাথে মেলে .*
।
মনে রাখবেন যে যদি কোনও লাইনে ডিজিটের একাধিক ক্রম থাকে তবে আপনার প্রোগ্রামটি সর্বকালের দীর্ঘতম ম্যাচের নিয়মের কারণে প্রাথমিকটিতে প্রয়োগ হওয়ার কারণে, সর্বদা অঙ্কের শেষ ক্রমটি বের করবে .*
। আপনি যদি অঙ্কগুলির প্রথম ক্রমটি বের করতে চান তবে আপনাকে অবশ্যই উল্লেখ করতে হবে যে এর আগে যা আসে তা অ-অঙ্কের ক্রম।
sed -n 's/^[^0-9]*\([0-9][0-9]*\).*$/\1/p'
আরও সাধারণভাবে, একটি রেজিএক্সএক্সের প্রথম ম্যাচটি এক্সট্রাক্ট করার জন্য আপনাকে সেই রেজিএক্সপ্যাকের অস্বীকৃতি গণনা করতে হবে। যদিও এটি সর্বদা তাত্ত্বিকভাবে সম্ভব, আপনি যে রেজিপেক্সটি উপেক্ষা করছেন তার আকারের সাথে প্রত্যাখ্যানের আকারটি তাত্পর্যপূর্ণভাবে বৃদ্ধি পায়, তাই এটি প্রায়শই অবৈধ।
আপনার অন্যান্য উদাহরণ বিবেচনা করুন:
sed -n 's/.*\(CONFIG_[a-zA-Z0-9_]*\).*/\1/p'
এই উদাহরণটি একই সমস্যাটি প্রদর্শন করে, তবে আপনি এটি সাধারণ ইনপুটগুলিতে দেখেন না। আপনি যদি এটি খাওয়ান hello CONFIG_FOO_CONFIG_BAR
, তবে উপরের কমান্ডটি প্রিন্ট করে CONFIG_BAR
, না CONFIG_FOO_CONFIG_BAR
।
সেডের সাথে প্রথম ম্যাচটি প্রিন্ট করার একটি উপায় রয়েছে তবে এটি কিছুটা জটিল:
sed -n -e 's/\(CONFIG_[a-zA-Z0-9_]*\).*/\n\1/' -e T -e 's/^.*\n//' -e p
(ধরে নিলাম আপনার শেড প্রতিস্থাপন পাঠ্যে \n
একটি নতুন লাইন বোঝায় mean s
) এটি কাজ করে কারণ সেড রেজিএক্সপেক্সের প্রথম দিকের ম্যাচটি সন্ধান করে, এবং আমরা CONFIG_…
কিছুটা আগে কী মিলবে তা চেষ্টা করি না । যেহেতু লাইনের ভিতরে কোনও নিউলাইন নেই, তাই আমরা এটিকে অস্থায়ী চিহ্নিতকারী হিসাবে ব্যবহার করতে পারি। T
কমান্ড ছেড়ে দিতে হবে যদি পূর্ববর্তী বলেছেন s
কমান্ড মেলেনি।
আপনি যখন কিছু উপায়ে কীভাবে করতে পারবেন তা যখন বুঝতে পারছেন না, ততক্ষণে ফিরে যান। নিম্নলিখিত কমান্ডটি একটি রেইগ এক্সপের সবচেয়ে দীর্ঘতম ম্যাচ মুদ্রণ করে:
awk 'match($0, /[0-9]+/) {print substr($0, RSTART, RLENGTH)}'
এবং যদি আপনি এটি সহজ রাখার মত বোধ করেন তবে পার্ল ব্যবহার করুন।
perl -l -ne '/[0-9]+/ && print $&' # first match
perl -l -ne '/^.*([0-9]+)/ && print $1' # last match