এডব্লিউকেতে নিয়মিত প্রকাশের লোভকে কীভাবে হ্রাস করা যায়?


14

আমি অ-লোভী প্যাটার্ন (নিয়মিত প্রকাশ) মেলাতে চাই awk। এখানে একটি উদাহরণ:

echo "@article{gjn, Author =   {Grzegorz J. Nalepa}, " | awk '{ sub(/@.*,/,""); print }'

সংক্ষিপ্ত স্ট্রিং নির্বাচন করে এমন নিয়মিত ভাব প্রকাশ করা কি সম্ভব?

@article{gjn,

এই দীর্ঘ স্ট্রিং এর পরিবর্তে ?:

@article{gjn, Author =   {Grzegorz J. Nalepa},

আমি এই ফলাফল পেতে চাই:

 Author =   {Grzegorz J. Nalepa},



আমার আরও একটি উদাহরণ রয়েছে:

প্রতিধ্বনি " , নিবন্ধ {gjn, লেখক = {গ্রজেগোর্স জে নালেপা}," | awk '; সাব (/ , [^,] *, /, ""); ছাপা }'
      ^^^^^ ↑ ^^^^^

নোট করুন যে আমি ইনপুট স্ট্রিং এবং নিয়মিত এক্সপ্রেশন উভয়ের প্রথম অবস্থানে @কমা ( ,) অক্ষরগুলিতে পরিবর্তন করেছি (এবং এতেও পরিবর্তন .*হয়েছে [^,]*)। সংক্ষিপ্ত স্ট্রিং নির্বাচন করে এমন নিয়মিত ভাব প্রকাশ করা কি সম্ভব?

, Author =   {Grzegorz J. Nalepa},

লম্বা স্ট্রিং এর পরিবর্তে ?:

,article{gjn, Author =   {Grzegorz J. Nalepa},

আমি এই ফলাফল পেতে চাই:

,article{gjn

4
শক্তিশালী এইচটিএমএল পার্সিংয়ের জন্য যেমন রেজেক্স অপর্যাপ্ত, তত সম্ভবত তারা এই ধরণের প্রসঙ্গ-সংবেদনশীল ব্যাকরণ পার্সিং করতে সক্ষম হবেন না। তবে, যদি আপনার ইনপুটগুলির সেটটি মোটামুটিভাবে সীমাবদ্ধ এবং সুগঠিত হয় তবে আপনি যতক্ষণ না আপনার বিধিনিষেধগুলি কী তা ঘোষণা করার পরে আপনি রেজিক্সের সাথে পালাতে সক্ষম হতে পারেন। উদাহরণস্বরূপ আপনি Authorকমা এবং হোয়াইটস্পেসের পরে সন্ধান করতে পারেন , হোয়াইটস্পেসের পরে =হোয়াইটস্পেসের পরে {কোনও অ- }অনুসরণ করবে }, যদিও এর জন্য (অন্যান্য জিনিসগুলির মধ্যে) প্রয়োজন যা আপনি অংশটির {}ভিতরে বাসাতে পারবেন না = { ... }
jw013

@ jw013, আপনার ব্যাখ্যার জন্য আপনাকে ধন্যবাদ। তবুও আমি অন্যান্য ব্যবহারকারীর পরামর্শের জন্য অপেক্ষা করব।
এখন

উত্তর:


18

আপনি যদি @তার ,পরে প্রথমটি নির্বাচন করতে এবং এটি করতে চান তবে আপনাকে এটি হিসাবে নির্দিষ্ট করতে হবে@[^,]*,

অর্থাৎ @কোনো নম্বর (দ্বারা অনুসরণ *অ কমা (এর) [^,]) একটি কমা দ্বারা অনুসরণ ( ,)।

এই পদ্ধতির সমতুল্য হিসাবে কাজ করে @.*?,তবে এই জাতীয় জিনিসের জন্য নয় @.*?string, এরপরে যা একক চরিত্রের চেয়ে বেশি। কোনও চরিত্রের নেতিবাচক কাজ করা সহজ, তবে রেগেক্সপসে স্ট্রিং অবহেলা করা আরও অনেক কঠিন

একটি ভিন্ন পদ্ধতির হ'ল আপনার ইনপুটটিকে stringএমন কোনও চরিত্রের সাথে প্রতিস্থাপন বা প্রেন্ডেন্ড করতে প্রাক প্রক্রিয়া করা যা অন্যথায় আপনার ইনপুটটিতে না ঘটে:

gsub(/string/, "\1&") # pre-process
gsub(/@[^\1]*\1string/, "")
gsub(/\1/, "") # revert the pre-processing

আপনি যদি গ্যারান্টি দিতে না পারেন যে ইনপুটটিতে আপনার প্রতিস্থাপনের অক্ষর ( \1উপরে) থাকবে না , তবে একটি পন্থা একটি পালানোর ব্যবস্থাটি ব্যবহার করা:

gsub(/\1/, "\1\3") # use \1 as the escape character and escape itself as \1\3
                   # in case it's present in the input
gsub(/\2/, "\1\4") # use \2 as our maker character and escape it
                   # as \1\4 in case it's present in the input
gsub(/string/, "\2&") # mark the "string" occurrences

gsub(/@[^\2]*\2string/, "")

# then roll back the marking and escaping
gsub(/\2/, "")
gsub(/\1\4/, "\2")
gsub(/\1\3/, "\1")

এটি স্থির strings এর জন্য কাজ করে তবে স্বেচ্ছাসেবী regexps এর মতো নয় এর সমতুল্য @.*?foo.bar


ভাল প্রতিক্রিয়া জন্য আপনাকে অনেক ধন্যবাদ। আমার সম্পাদনায় আমি আরও একটি উদাহরণ জিজ্ঞাসা করেছি (আমার সম্পাদনা দেখুন)।
এখন 1

6

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

পার্লের একটি অ-লোভী অপারেটর রয়েছে যা পার্ল স্ক্রিপ্টগুলিতে এবং যে কোনও কিছুতে পিসিআরই ব্যবহার করে। উদাহরণস্বরূপ, জিএনইউ গ্রেপের বিকল্পেও প্রয়োগ করা হয়েছে -P

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

থেকে perlre (1) man পৃষ্ঠা:

   By default, a quantified subpattern is "greedy", that is, it will match
   as many times as possible (given a particular starting location) while
   still allowing the rest of the pattern to match.  If you want it to
   match the minimum number of times possible, follow the quantifier with
   a "?".  Note that the meanings don't change, just the "greediness":

       *?        Match 0 or more times, not greedily
       +?        Match 1 or more times, not greedily
       ??        Match 0 or 1 time, not greedily
       {n}?      Match exactly n times, not greedily (redundant)
       {n,}?     Match at least n times, not greedily
       {n,m}?    Match at least n but not more than m times, not greedily

3

এটি একটি পুরানো পোস্ট, তবে নিম্নলিখিত তথ্যগুলি অন্যদের জন্য কার্যকর হতে পারে।

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

if (match(string, RE)) {
    rstart = RSTART
    for (i=RLENGTH; i>=1; i--)
        if (!(match(substr(string,1,rstart+i-1), RE))) break;
    # At this point, the non-greedy match will start at rstart
    #  for a length of i+1
}

2

সাধারণ প্রকাশের জন্য, এটি একটি লোভী মিল হিসাবে ব্যবহার করা যেতে পারে:

function smatch(s, r) {
    if (match(s, r)) {
        m = RSTART
        do {
            n = RLENGTH
        } while (match(substr(s, m, n - 1), r))
        RSTART = m
        RLENGTH = n
        return RSTART
    } else return 0
}

আমি @ জিমমেল্যান্ডারের উত্তরের ভিত্তিতে এটি ব্যবহার করছি। ফিরে আসার smatchমতো আচরণ করে match:

s যেখানে নিয়মিত প্রকাশ rহয় সেখানে অবস্থান বা 0 না হলে 0। ভেরিয়েবলগুলি RSTARTএবং RLENGTHম্যাচ করা স্ট্রিংয়ের অবস্থান এবং দৈর্ঘ্যে সেট করা আছে।


1

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

awk '{ sub(/@.*Author/,"Author"); print }'

লেখকের আগের অক্ষরের সংখ্যা যদি সর্বদা একই থাকে তবে আপনি এটি করতে পারেন:

awk '{ sub(/@.{21}/,""); print }'

পুরো সেটটি জুড়ে আপনার ডেটা দেখতে কেমন তা আপনাকে কেবল জানতে হবে।


0

একটি উপায় সবসময় আছে. প্রদত্ত সমস্যাটি বিভাজক হিসাবে কমা ব্যবহার করে মোটামুটি সহজে সমাধান করা যায়।

echo "@article{gjn2010jucs, Author =   {Grzegorz J. Nalepa}, " |
awk -F, '{sub(/^[ \t]/, "", $2); print $2}'

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

echo "@article{gjn2010jucs, Author =   {Grzegorz J. Nalepa}, " |
awk  '{sub(/.*Author/, "Author", $0); sub(/},.*/, "}", $0); print $0}'

0

আমি জানি এটি একটি পুরানো পোস্ট। তবে অনুরোধ হিসাবে ঠিক
ওকে হিসাবে অ্যাডকে ব্যবহার করার মতো কিছু এখানে রয়েছে: এ = @ নিবন্ধ {gjn2010jucs, লেখক = {গ্রজেগোর্জ জে নালেপা},
প্রতিধ্বনি $ এ | অজক 'সাব (/ @ [^,] * /, "")' '

আউটপুট
:, লেখক = {গ্রজেগোর্জ জে নালেপা},


1
এই উত্তরটি প্রায় পাঁচটি কারণে ভুল।
স্কট

3
আপনি কি দয়া করে আমাকে ভুল বুঝতে সাহায্য করতে পারেন? আউটপুট অনুরোধ করা হয় কি সামঞ্জস্যপূর্ণ বলে মনে হচ্ছে। উত্তরটি কেন সঠিক / সঠিক নয় তা বোঝার চেষ্টা করছি।
বিন নায়ার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.