সমস্ত 10 অক্ষরের শব্দের জন্য রেজেক্স, অনন্য বর্ণ সহ


23

আমি একটি রেজেক্স লেখার চেষ্টা করছি যা 10 টি অক্ষরের দীর্ঘ সমস্ত শব্দ প্রদর্শন করবে এবং কোনও অক্ষরই পুনরাবৃত্তি করছে না।

এখন পর্যন্ত, আমি পেয়েছি

grep --colour -Eow '(\w{10})'

যা প্রশ্নের প্রথম অংশ। আমি কীভাবে "স্বতন্ত্রতা" পরীক্ষা করতে যাব? আমার সত্যিই কোনও ধারণা নেই, এর বাইরে আমার পিছনে উল্লেখগুলি ব্যবহার করা দরকার।


1
এটি অবশ্যই একটি রেইজেক্স দিয়ে করা উচিত?
Hauke ​​লেগেছে

আমি রেইগেক্স অনুশীলন করছি, তাই সম্ভবত হ্যাঁ :)
ডিলান মিউস

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

3
@ ব্রুসইডিগার যতক্ষণ না ভাষার (26) অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে থাকে (10), এটি করা সম্ভব। এটি কেবল অনেকগুলি রাজ্য, তবে এমন কোনও কিছুই যা এটি নিয়মিত ভাষা হিসাবে তৈরি করে না।

1
আপনার অর্থ "সমস্ত ইংরেজি শব্দ ..."? হাইফেন এবং অ্যাডোস্ট্রোফের সাথে বানানগুলি অন্তর্ভুক্ত করার অর্থ কি আপনি (শ্বাশুড়ী, না)? আপনি কি ক্যাফে, স্নিগ্ধ, ফলক হিসাবে শব্দ অন্তর্ভুক্ত বোঝাতে চান?
হিপ্পিট্রেইল

উত্তর:


41
grep -Eow '\w{10}' | grep -v '\(.\).*\1'

দুটি শব্দ অভিন্ন অক্ষরযুক্ত শব্দগুলি বাদ দেয়।

grep -Eow '\w{10}' | grep -v '\(.\)\1'

পুনরাবৃত্তি করা অক্ষরগুলি বাদ দেয়।

POSIXly:

tr -cs '[:alnum:]_' '[\n*]' |
   grep -xE '.{10}' |
   grep -v '\(.\).*\1'

trsশব্দহীন-অক্ষরগুলির কোনও সমীকরণ ( cআলফা-সংখ্যাসূচক ও আন্ডারস্কোরের সমাপ্তি) কে একটি নতুন লাইনের চরিত্রে রূপান্তর করে শব্দগুলিকে তাদের নিজস্ব লাইনে রাখে ।

বা একটি সহ grep:

tr -cs '[:alnum:]_' '[\n*]' |
   grep -ve '^.\{0,9\}$' -e '.\{11\}' -e '\(.\).*\1'

(10 টিরও কম এবং 10 টিরও বেশি অক্ষরের লাইনগুলি বাদ দিন এবং একটি চরিত্রের অন্তত দু'বার প্রদর্শিত হবে)।

grepকেবল একটির সাথে (পিসিআরই সমর্থন সহ জিএনইউ গ্রেপ বা pcregrep):

grep -Po '\b(?:(\w)(?!\w*\1)){10}\b'

এটি হ'ল, একটি শব্দ সীমানা ( \b) এর পরে 10 টি শব্দের অক্ষরের ক্রম হয় (প্রতিটি শব্দের অক্ষরের ক্রম এবং তাদের অনুসরণ না করে, নেতিবাচক চেহারা-সামনের PCRE অপারেটর ব্যবহার করে (?!...))।

আমরা ভাগ্যবান যে এটি এখানে কাজ করে, কারণ অনেকগুলি রেজিপ এক্স ইঞ্জিন পুনরাবৃত্তি অংশগুলির অভ্যন্তরে ব্যাকরিফারেন্স সহ কাজ করে না।

নোট করুন (কমপক্ষে GNU গ্রেপের আমার সংস্করণ সহ)

grep -Pow '(?:(\w)(?!\w*\1)){10}'

কাজ করে না, কিন্তু

grep -Pow '(?:(\w)(?!\w*\2)){10}'

(যেমন echo aa | grep -Pw '(.)\2') যা বাগের মতো শোনাচ্ছে does

তুমি চাইতে পারো:

grep -Po '(*UCP)\b(?:(\w)(?!\w*\1)){10}\b'

আপনি যদি চান \wবা \bকোনও অক্ষরকে শব্দের উপাদান হিসাবে বিবেচনা করেন এবং কেবলমাত্র ASCII নয় এমন লোকেলগুলিতে নয়।

অন্য বিকল্প:

grep -Po '\b(?!\w*(\w)\w*\1)\w{10}\b'

এটি একটি শব্দের সীমানা (শব্দের অক্ষরের ক্রম দ্বারা অনুসরণ করা হয় না এমন একটি যার পুনরাবৃত্তি হয়) এর পরে 10 শব্দ অক্ষর হয়।

কারও মনের পিছনে থাকা জিনিসগুলি:

  • তুলনাটি কেস সংবেদনশীল, সুতরাং Babylonishউদাহরণস্বরূপ মিলানো হবে, যেহেতু দুটি অক্ষর B, একটি নিম্ন এবং একটি উচ্চতর কেস থাকলেও সমস্ত অক্ষর আলাদা হয় ( -iএটি পরিবর্তন করতে ব্যবহার করুন )।
  • জন্য -w, \wএবং \b, একটি শব্দ (হওয়া ASCII বেশী শুধুমাত্র গনুহ জন্য একটি চিঠি grep এখন জন্য , [:alpha:]আপনার লোকেলে চরিত্র শ্রেণী যদি ব্যবহার -Pএবং (*UCP)), দশমিক সংখ্যা বা আন্ডারস্কোর
  • এর অর্থ হ'ল c'est(কোনও শব্দের ফরাসি সংজ্ঞা অনুসারে দুটি শব্দ) বা it's( কোনও শব্দের কিছু ইংরেজী সংজ্ঞা অনুসারে একটি শব্দ) বা rendez-vous(কোনও শব্দের ফরাসী সংজ্ঞা অনুসারে একটি শব্দ) একটি শব্দ হিসাবে বিবেচিত হয় না।
  • এমনকি (*UCP)ইউনিকোড সংমিশ্রিত অক্ষরগুলিকে শব্দের উপাদান হিসাবে বিবেচনা করা হয় না, সুতরাং téléphone( $'t\u00e9le\u0301phone') 10 টি অক্ষর হিসাবে বিবেচনা করা হয়, যার মধ্যে একটি নন-আলফা। défavorisé( $'d\u00e9favorise\u0301') এটি দুটি মিলিয়েও মিলবে éকারণ এটি 10 ​​টির মধ্যে বিভিন্ন আলফা অক্ষর এবং তার পরে সম্মিলিত তীব্র উচ্চারণ (নন-আলফা, সুতরাং eএবং এর উচ্চারণের মধ্যে একটি শব্দ সীমানা রয়েছে)।

1
অসাধারণ. যদিও \wমেলে -না।
গ্রায়েম

@ স্টাফেন আপনি শেষ দুটি অভিব্যক্তির সংক্ষিপ্ত বিবরণ পোস্ট করতে পারেন।
এমকেসি

কখনও কখনও দেখে মনে হয় যে আরআর দিয়ে অসম্ভব বলে ব্যবহার করা সমস্ত জিনিসগুলির সমাধান হ'ল রূপগুলি।
বার্মার

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

1
@ জুলস এটি unix.stackexchange.com, math.stackexchange.com নয় ke গাণিতিক আরআরই এই প্রসঙ্গে অপ্রাসঙ্গিক, আমরা গ্রিপ, পিসিআরই ইত্যাদির মাধ্যমে আপনি যে ধরণের আরই ব্যবহার করেন সে সম্পর্কে কথা বলছি
বার্মার

12

ঠিক আছে ... এখানে পাঁচটি চরিত্রের স্ট্রিংয়ের আড়ম্বরপূর্ণ উপায়:

grep -P '^(.)(?!\1)(.)(?!\1|\2)(.)(?!\1|\2|\3)(.)(?!\1|\2|\3|\4).$'

আপনি কোনও অক্ষর শ্রেণিতে (যেমন [^\1|\2]) কোনও পিছনের রেফারেন্স রাখতে পারবেন না , আপনাকে অবশ্যই একটি নেতিবাচক চেহারা- ব্যবহার করতে হবে - (?!foo)। এটি একটি পিসিআরই বৈশিষ্ট্য তাই আপনার -Pসুইচটি দরকার ।

10 টি অক্ষরের স্ট্রিংয়ের প্যাটার্নটি অবশ্যই অনেক দীর্ঘ হবে, তবে লুকের হেডে ভেরিয়েবলের দৈর্ঘ্যের যে কোনও কিছু ম্যাচ ('। *') ব্যবহার করে একটি ছোট পদ্ধতি রয়েছে:

grep -P '^(.)(?!.*\1)(.)(?!.*\2)(.)(?!.*\3)(.)(?!.*\4)(.)(?!.*\5).$'

স্টিফেন চেজেলাসের আলোকিত উত্তরটি পড়ার পরে আমি বুঝতে পেরেছি যে গ্রেপের -vসুইচের মাধ্যমে এই ব্যবহারের জন্য একই ধরণের সহজ প্যাটার্ন রয়েছে :

    (.).*\1

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

grep -v '\(.\).*\1'

অনন্য অক্ষর সহ যে কোনও দৈর্ঘ্যের একটি স্ট্রিং সনাক্ত করতে কাজ করবে যখন:

grep -P '(.)(?!.*\1)'

হ'ল না, যেহেতু এটি অনন্য অক্ষরের সাথে প্রত্যয়টির সাথে abcabcমিলবে (উদাহরণস্বরূপ ম্যাচগুলি abcশেষের aaaaকারণে aএবং শেষের কারণে - সুতরাং কোনও স্ট্রিং)। এটি শূন্য-প্রস্থের (এগুলি কোনও কিছুই গ্রাস করে না) দেখা দেওয়ার কারণে সৃষ্ট একটি জটিলতা।


সাবাশ! এটি কেবলমাত্র Q এর সাথে একত্রে কাজ করবে।
গ্রীম

1
আমি বিশ্বাস করি যদি আপনার রেজেক্স ইঞ্জিনটি চলক দৈর্ঘ্যের নেতিবাচক (.)(?!.*\1)(.)(?!.*\2)(.)(?!.*\3)(.)(?!\4).
বর্ণনাকে

@ ক্রিস্টোফার ক্রিউটজিগ: একেবারে, দুর্দান্ত কল। আমি এটি এতে যুক্ত করে রেখেছি
সোনারলকস

6

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

perl -nle 'MATCH:while(/\W(\w{10})\W/g){
             undef %seen;
             for(split//,$1){next MATCH if ++$seen{$_} > 1}
             print
           }' your_file

অতিরিক্ত \Wনোঙ্গরগুলি লক্ষ্য করুন যে কেবল 10 টি অক্ষরের সাথে লম্বা শব্দগুলির সাথে মিল রয়েছে।


আপনাকে ধন্যবাদ, তবে আমি এটি একটি রেজিেক্স অনেলাইনার হিসাবে চাই :)
ডিলান মিউস

4

অন্যরা পরামর্শ দিয়েছেন যে নির্দিষ্ট নিয়মিত এক্সপ্রেশন সিস্টেমগুলিতে বিভিন্ন এক্সটেনশন ব্যতীত এটি সম্ভব নয় যা বাস্তবে নিয়মিত নয়। তবে যেহেতু আপনি যে ভাষাটি মেলে দেখতে চান তা সীমাবদ্ধ, এটি স্পষ্টভাবে নিয়মিত। 4-অক্ষরের বর্ণমালা থেকে 3 টি বর্ণের জন্য, এটি সহজ হবে:

(abc|abd|acb|acd|bac|bad|bcd|bdc|cab|cad|cbd|cdb|dab|dac|dbc|dcb)

স্পষ্টতই আরও চিঠি এবং আরও বড় বর্ণমালা সহ তাড়াহুড়োয় এটি হাতছাড়া হয়ে যায়। :-)


আমাকে এটি আপভোট করতে হয়েছিল কারণ এটি আসলে একটি উত্তর যা কাজ করবে। যদিও এটি এখন পর্যন্ত কেউ সবচেয়ে সহজ উপায় হতে পারে রেগেক্স লিখেছেন: পি
ডিলান মিউস

4

GNU এর অপশন --perl-regexp(সংক্ষিপ্ত -P) grepআরও শক্তিশালী নিয়মিত এক্সপ্রেশন ব্যবহার করে যা সামনের ধরণগুলি অন্তর্ভুক্ত করে। নিম্নলিখিত প্যাটার্নটি প্রতিটি অক্ষরের সন্ধান করে যা এই অক্ষরটি শব্দের অবশিষ্টাংশে উপস্থিত হয় না:

grep -Pow '((\w)(?!\w*\g{-1})){10}'

তবে রান-টাইম আচরণটি বেশ খারাপ, কারণ এর \w*দৈর্ঘ্য প্রায় অসীম হতে পারে। এটি সীমাবদ্ধ হতে পারে \w{,8}তবে এটি 10 ​​টি অক্ষরের শব্দের সীমা ছাড়িয়েও পরীক্ষা করে। সুতরাং নিম্নলিখিত প্যাটার্নটি প্রথমে সঠিক শব্দের দৈর্ঘ্য পরীক্ষা করে:

grep -Pow '(?=\w{10}\b)((\w)(?!\w*\g{-1})){10}'

পরীক্ষার ফাইল হিসাবে আমি একটি বড় ≈ 500 এমবি ফাইল ব্যবহার করেছি:

  • প্রথম প্যাটার্ন: ≈ 43 এস
  • ল্যাটার্ন প্যাটার্ন: 15 ডলার

হালনাগাদ:

অ-লোভী অপারেটর ( \w*?) বা অধিকারী অপারেটর ( (...){10}+) এর জন্য রান-টাইম আচরণে আমি উল্লেখযোগ্য পরিবর্তন খুঁজে পেলাম না । সামান্য কিছুটা দ্রুত বিকল্পের প্রতিস্থাপন বলে মনে হচ্ছে -w:

grep -Po '\b(?=\w{10}\b)((\w)(?!\w*\g{-1})){10}\b'

2.13 সংস্করণ থেকে 2.18 সংস্করণ পর্যন্ত গ্রেপের একটি আপডেট আরও কার্যকর ছিল। পরীক্ষার ফাইলটি কেবল ≈ 6 ডলারে নিয়েছিল।


পারফরম্যান্স ডেটা প্রকৃতির উপর অনেক নির্ভর করবে। খনিতে পরীক্ষা করার সময়, আমি দেখতে পেলাম যে অ-লোভী অপারেটরগুলি ( \w{,8}?) ব্যবহার করে কিছু ধরণের ইনপুট (যদিও খুব তাৎপর্যপূর্ণ নয়) ব্যবহারে সহায়তা করা হয়েছে। \g{-1}জিএনইউ গ্রেপ বাগের চারপাশে কাজ করার জন্য দুর্দান্ত ব্যবহার ।
স্টাফেন চেজেলাস

@ স্টাফেনচাজেলাস: প্রতিক্রিয়ার জন্য ধন্যবাদ। আমি অ-লোভী এবং অধিকারী অপারেটরদেরও চেষ্টা করেছি এবং রান-টাইম আচরণে (সংস্করণ ২.১13) কোনও উল্লেখযোগ্য পরিবর্তন পাইনি। সংস্করণ 2.18 অনেক দ্রুত এবং আমি কমপক্ষে একটি সামান্য উন্নতি দেখতে পেয়েছি। জিএনইউ গ্রেপ বাগ উভয় সংস্করণে উপস্থিত রয়েছে। যাইহোক আমি আপেক্ষিক রেফারেন্সটি পছন্দ করি \g{-1}, কারণ এটি অবস্থানটিতে নিদর্শনটিকে আরও স্বতন্ত্র করে তোলে। এই ফর্ম এ এটি একটি বৃহত প্যাটার্ন অংশ হিসাবে ব্যবহার করা যেতে পারে।
হাইকো ওবারডিক

0

একটি পার্ল সমাধান:

perl -lne 'print if (!/(.)(?=$1)/g && /^\w{10}$/)' file

তবে এটি কাজ করে না

perl -lne 'print if (!/(.)(?=\1)/g && /^\w{10}$/)' file

অথবা

perl -lne 'print if ( /(.)(?!$1)/g && /^\w{10}$/)' file

পার্ল v5.14.2 এবং v5.18.2 দিয়ে পরীক্ষিত


1 ম এবং 3 য় কিছুই করে না, 2 য় 10 বা ততোধিক অক্ষরের কোনও লাইন আউটপুট দেয়, পরপর 2 টির বেশি স্পেস ছাড়াই। পেস্টবিন.
com

এটি সম্ভবত পার্ল সংস্করণ। v5.14.2 এবং v5.18.2

আমি তাদের লিনাক্সে v5.14.1 এবং সাইগউইনে v5.14.2 দিয়ে চেষ্টা করেছি। দু'জনেই আগে যুক্ত লিখিত পেস্টবিনের নমুনার মতো আচরণ করেছিলেন।
manatwork

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

আপনার সর্বশেষ আপডেটের সাথে প্রতিক্রিয়া জানানো হয়েছে। শুধুমাত্র ২ য় এক সঠিকভাবে আউটপুট দেয়। (তবে শব্দটি অবশ্যই একটি লাইনে একা থাকতে হবে, যখন প্রশ্নটি মিলনের শব্দের বিষয়ে, পুরো লাইন নয়
not
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.