چگونه می توان عبارات معمولی جمع و جور را در روبی تولید کرد؟

مقدمه
ایجاد عبارات منظم جمع و جور از لیست اعداد صحیح ، یک مهارت مفید در برنامه نویسی است ، به خصوص هنگام برخورد با قوانین اعتبار سنجی. در این مقاله ، ما چگونگی تولید پویا یک بیان منظم در روبی را کشف خواهیم کرد که دامنه های اعداد صحیح را به صورت فشرده ضبط می کند. با توجه به لیستی از اعداد صحیح ، ما یاد می گیریم که الگوهای regex مانند تولید کنیم /^([1-7]|9|1[0-5]|1[7-9]|2[0-3]|2[5-9]|3[0-1])$/
بشر این regex باید به طور مؤثر فقط با شماره های مشخص شده با کارآمدترین روش مطابقت داشته باشد.
چرا مهم است؟
تولید عبارات معمولی جمع و جور به بهبود عملکرد در حین تطبیق الگوی رشته کمک می کند. این می تواند باعث کاهش پیچیدگی و افزایش خوانایی شود که هنگام حفظ کد بسیار مهم است. اگر به درستی اجرا نشود ، هیچ پس انداز قابل توجهی در عملکرد یا خوانایی حاصل نمی شود ، و نوشتن کد قوی و در عین حال ساده برای این کار ضروری است.
درک اجرای فعلی
کد یاقوت ارائه شده به چندین کارکرد تقسیم می شود ، با هدف گروه بندی اعداد صحیح به محدوده و تبدیل این محدوده ها به عبارات منظم. مسئله اصلی ناشی از یک فرآیند تولید regex ناکارآمد است که منجر به یک regex کلامی و بیش از حد پیچیده می شود.
توابع توضیح داده شده است
- number_list_to_ranges (اعداد): این عملکرد اعداد صحیح متوالی را جمع می کند و مجموعه ای از دامنه ها را برمی گرداند.
- range_to_regex (r): این عملکرد سعی می کند یک شیء دامنه را به یک رشته بیان منظم تبدیل کند اما نمی تواند دامنه های جمع و جور را نشان دهد ، که این نیاز اصلی است.
- generate_regex (اعداد): عملکرد رانندگی که با استفاده از دو عملکرد قبلی بر تولید Regex جمع و جور متمرکز است.
راه حل: بهبود تولید منظم بیان
بیایید تقویت کنیم range_to_regex
عملکرد برای رسیدگی به درستی از تحولات دامنه و بهبود منطق کلی نسل Regex. در اینجا یک نسخه اصلاح شده از کد وجود دارد:
def number_list_to_ranges(numbers)
numbers.sort!
ranges = []
start = numbers.first
prev = numbers.first
numbers[1..].each do |n|
if n == prev + 1
prev = n
else
ranges << (start..prev)
start = n
prev = n
end
end
ranges << (start..prev)
end
# Improved range_to_regex function
def range_to_regex(r)
return r.begin.to_s if r.begin == r.end
if r.begin >= 0 && r.end <= 9
"[#{r.begin}-#{r.end}]"
elsif r.begin >= 10 && r.end <= 99
tens = r.begin / 10
units_start = r.begin % 10
units_end = r.end % 10
if r.begin / 10 == r.end / 10 # Same tens
"#{tens}[#{units_start}-#{units_end}]"
else
(r.begin..r.end).map(&:to_s).join('|')
end
else
(r.begin..r.end).map(&:to_s).join('|')
end
end
def generate_regex(numbers)
ranges = number_list_to_ranges(numbers.uniq)
parts = ranges.map { |r| range_to_regex(r) }
"/^(" + parts.join('|') + ")$/"
end
nums = [1,2,3,4,5,6,7,9,10,11,12,13,14,15,17,18,19,20,21,22,23,25,26,27,28,29,30,31]
puts generate_regex(nums)
تنظیمات توضیح داده شد
- در
range_to_regex
عملکرد برای کنترل موثرتر اصلاح شده است. به طور خاص ، بررسی می کند که آیا شروع و پایان دامنه در همان TENS به اشتراک می گذارد ،1[0-5]
برای دامنه 10 تا 15. - برای تأیید صحت ، regex حاصل فقط شامل اعداد صحیح مشخص شده است ، به طور فشرده نمایانگر دامنه ها و صرفه جویی در فضای است.
پرسش
این کد با چه نوع ورودی کار می کند؟
این کد لیستی از عدد صحیح را می پذیرد و آنها را مرتب می کند تا الگوهای REGEX جمع و جور را تشکیل دهد. این تعداد هم به طور مداوم و هم به طور مؤثر از تعداد آنها برخوردار است.
آیا این می تواند برای سایر محدوده ها سفارشی شود؟
بله شما می توانید شرایط موجود در range_to_regex
برای قرار دادن دامنه یا قالب های مختلف در صورت لزوم.
چگونه می توانم خروجی Regex تولید شده را آزمایش کنم؟
شما می توانید رشته خروجی Regex را در برابر داده های نمونه با استفاده از روش های داخلی REGEX Ruby آزمایش کنید تا اطمینان حاصل شود که با شماره های مورد نظر دقیق مطابقت دارد.
پایان
تولید عبارات معمولی جمع و جور می تواند به طور موثر در یاقوت با برخی از اصلاحات رویه ای انجام شود. با شناخت صحیح دامنه ها ، ما می توانیم ضمن افزایش خوانایی و حفظ کد ، بازده Regex خود را اقتصادی کنیم. با استفاده از اجرای ارائه شده ، می توانید مطابق با الزامات پروژه خود ، این مفهوم را بیشتر سازگار و گسترش دهید.