কীভাবে কোনও রেজেক্সের সমস্ত উপস্থিতি মেলে


585

রুবিতে নিয়মিত প্রকাশের প্রতিটি মিল খুঁজে পাওয়ার কী দ্রুত উপায় আছে? আমি রুবি এসটিএলে রেজেক্স বস্তুটি দেখেছি এবং গুগলে অনুসন্ধান করেছি কোনও লাভ হয়নি।


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

উত্তর:


820

ব্যবহারের scanকৌশলটি করা উচিত:

string.scan(/regex/)

9
তবে এ ক্ষেত্রে কী হবে? "মেলে আমাকে!"। স্ক্যান (/.../) = ["মাদুর", "সিএইচ" "আমাকে!" ], তবে /.../ এর সমস্ত উপস্থিতি ["মাদুর", "এটিসি", "টিচ", "সিএইচ", ...]
মাইকেল ডিকেন্স

13
এটা হবে না। /.../ হ'ল একটি সাধারণ লোভী রিজ এক্সপ্যাক্স। এটি মিলে যাওয়া সামগ্রীতে ব্যাকট্র্যাক করবে না। আপনি একটি অলস regexp ব্যবহার করার চেষ্টা করতে পারেন তবে এটি সম্ভবত যথেষ্ট হবে না। regexp ডক কটাক্ষপাত আছে ruby-doc.org/core-1.9.3/Regexp.html সঠিকভাবে আপনার regexp প্রকাশ করার :)
জাঁ

49
এটি রুবি ডাব্লুটিএফের মতো মনে হচ্ছে ... স্ট্রিং-এ অন্য রেজিএক্সএফের পরিবর্তে রেজিএক্সপ্যাকের পরিবর্তে এটি কেন? এমনকি এটি রেজিএক্সপক্সের জন্য ডক্সে কোথাও উল্লেখ করা হয়নি
এ্যানট্রপিক

8
আমার ধারণা এটি এর কারণ এটি সংজ্ঞায়িত করা হয়েছে এবং স্ট্রিংকে রিজেক্সে নয় বরং বলা হয়েছিল ... তবে এটি আসলে তা বোঝায় না। আপনি রেগেক্স # ম্যাচ ব্যবহার করে সমস্ত ম্যাচ ক্যাপচারের জন্য নিয়মিত অভিব্যক্তি লিখতে পারেন এবং বন্দী গোষ্ঠীগুলিতে পুনরাবৃত্তি করতে পারেন। এখানে আপনি একটি আংশিক ম্যাচ ফাংশন লিখুন এবং এটি একটি নির্দিষ্ট স্ট্রিংয়ের উপর একাধিকবার প্রয়োগ করতে চান, এটি রেজিএক্সপেক্সের দায়িত্ব নয়। আমি তোমাদের ভাল করে বুঝতে জন্য স্ক্যান বাস্তবায়ন পরীক্ষা সুপারিশ: ruby-doc.org/core-1.9.3/String.html#method-i-scan
জাঁ

9
@ মিশেলডিকেনস: এই ক্ষেত্রে, আপনি ব্যবহার করতে পারেন /(?=(...))/
কনরাড বোরোস্কি

67

সমস্ত মিলে যাওয়া স্ট্রিংগুলি সন্ধান করতে স্ট্রিংয়ের scanপদ্ধতিটি ব্যবহার করুন ।

str = "A 54mpl3 string w1th 7 numb3rs scatter36 ar0und"
str.scan(/\d+/)
#=> ["54", "3", "1", "7", "3", "36", "0"]

আপনি যদি চান তবে MatchDataযা রেজেপেক্স matchপদ্ধতিতে প্রত্যাবর্তিত অবজেক্টের ধরণ, এটি ব্যবহার করুন:

str.to_enum(:scan, /\d+/).map { Regexp.last_match }
#=> [#<MatchData "54">, #<MatchData "3">, #<MatchData "1">, #<MatchData "7">, #<MatchData "3">, #<MatchData "36">, #<MatchData "0">]

ব্যবহারের সুবিধা MatchDataহ'ল আপনি এই জাতীয় পদ্ধতি ব্যবহার করতে পারেন offset:

match_datas = str.to_enum(:scan, /\d+/).map { Regexp.last_match }
match_datas[0].offset(0)
#=> [2, 4]
match_datas[1].offset(0)
#=> [7, 8]

আপনি আরও জানতে চাইলে এই প্রশ্নগুলি দেখুন:

বিশেষ ভেরিয়েবল সম্পর্কে পড়া $&, $', $1, $2রুবি সহায়ক বলে প্রমাণিত হবে।


12

আপনার যদি গ্রুপগুলির সাথে একটি রেজিপ্স থাকে:

str="A 54mpl3 string w1th 7 numbers scatter3r ar0und"
re=/(\d+)[m-t]/

scanমিলে যাওয়া গ্রুপগুলি খুঁজতে আপনি স্ট্রিংয়ের পদ্ধতিটি ব্যবহার করতে পারেন :

str.scan re
#> [["54"], ["1"], ["3"]]

মিলের প্যাটার্নটি সন্ধান করতে:

str.to_enum(:scan,re).map {$&}
#> ["54m", "1t", "3r"]

str.scan(/\d+[m-t]/) # => ["54m", "1t", "3r"]str.to_enum(:scan,re).map {$&}
টিন ম্যান

আপনি ভুল বুঝতে পারে। একটি ব্যবহারকারী আমি উত্তর উদাহরণ কয়েক রেগুলার এক্সপ্রেশন ছিল: /(\d+)[m-t]/না /\d+[m-t]/লিখতে: re = /(\d+)[m-t]/; str.scan(re)একই str.scan(/(\d+)[mt]/)কিন্তু আমি # যাক> [["" 54 "], [" 1 "], [" 3 "]]এবং "54m", "1t", "3r"]প্রশ্ন ছিল: যদি আমি একটি দলের সঙ্গে একটি রেগুলার এক্সপ্রেশন আছে এবং নিয়মিত পরিবর্তন না করে সমস্ত নিদর্শন ক্যাপচার করতে চান এক্সপ্রেশন (গ্রুপ ছেড়ে), আমি কীভাবে এটি করতে পারি? এই অর্থে, একটি সম্ভাব্য সমাধান, যদিও কিছুটা রহস্যজনক এবং পড়তে অসুবিধা ছিল, তা ছিল:str.to_enum(:scan,re).map {$&}
এমভিপি

-1

আপনি ব্যবহার করতে পারেন string.scan(your_regex).flatten। যদি আপনার রেজেক্সে গোষ্ঠী থাকে তবে এটি একটি একক সরল অ্যারেতে ফিরে আসবে।

string = "A 54mpl3 string w1th 7 numbers scatter3r ar0und"
your_regex = /(\d+)[m-t]/
string.scan(your_regex).flatten
=> ["54", "1", "3"]

Regex পাশাপাশি একটি নামী গ্রুপ হতে পারে।

string = 'group_photo.jpg'
regex = /\A(?<name>.*)\.(?<ext>.*)\z/
string.scan(regex).flatten

আপনি gsubম্যাচটাটা চাইলে এটি আরও একটি উপায়ে ব্যবহার করতে পারেন।

str.gsub(/\d/).map{ Regexp.last_match }

এর থেকে গ্রুপিং সরিয়ে ফেলুন your_regex = /(\d+)[m-t]/এবং আপনার ব্যবহারের প্রয়োজন হবে না flatten। আপনার চূড়ান্ত উদাহরণটি ব্যবহার করে last_matchযা সম্ভবত এটি নিরাপদ তবে এটি একটি বিশ্বব্যাপী এবং সম্ভবত কল করার আগে কোনও রেজেক্স ম্যাচ করা থাকলে ওভাররাইট করা যেতে পারে last_match। পরিবর্তে এটি প্যাটার্ন এবং প্রয়োজনীয়তার উপর নির্ভর করে সম্ভবত ব্যবহার করা নিরাপদ string.match(regex).captures # => ["group_photo", "jpg"]বা string.scan(/\d+/) # => ["54", "3", "1", "7", "3", "0"]অন্যান্য উত্তরে যেমন দেখানো হয়েছে।
টিন ম্যান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.