কম্পিউটার টিউটোরিয়াল

রুবি স্ট্রিং এস্কেপিং মাস্টার করুন: কোট এবং স্পেশাল ক্যারেক্টার হ্যান্ডলিং

এই পোস্টে আমরা রুবিতে ক্যারেক্টার এস্কেপিং নিয়ে কথা বলব। আমরা শিখব কীভাবে ক্যারেক্টার এস্কেপ করতে হয়, কীভাবে সেটি কাজ করে, এবং কিছু ইউজ কেসে এস্কেপিং সম্পূর্ণ এড়িয়ে যাওয়া যাবে। আপনি যদি মনে করেন আপনি \ সম্পর্কে সব জানেন, পুরোটা পড়ুন এবং বিস্মিত হন...

স্ট্রিং-এ ক্যারেক্টার এস্কেপিং-এ ডুব যাই।

কোট এস্কেপ করা

রুবিতে স্ট্রিং ব্যবহার করার সময়, আমরা কখনো কখনো স্ট্রিং ডিফাইন করতে যে কোট ব্যবহার করেছি সেটি স্ট্রিং-এর ভেতরেই রাখতে চাই। যখন আমরা সেটি করি, আমরা কোট ক্যারেক্টারকে ব্যাকস্ল্যাশ \ সিম্বল দিয়ে এস্কেপ করতে পারি।

# Escape quotes in double quoted strings
"Hello \"world\"!" => "Hello \"world\"!"
# Escape quotes in single quoted strings
'Hello \'world\'!' => "Hello 'world'!"

এখানে আমরা দেখতে পাচ্ছি রুবি আউটপুটের জন্য ডিফল্টভাবে ডবল কোটেড স্ট্রিং ব্যবহার করে এবং শুধু সেগুলো ডবল কোট আউটপুটে এস্কেপ করে।

এস্কেপ সিকোয়েন্স

কোটের পাশাপাশি, আরও সিম্বল আছে যেগুলো স্ট্রিং-এ এস্কেপ করা যায়। উদাহরণস্বরূপ, একটি নিউলাইন রিপ্রেজেন্ট করা হয় \n দিয়ে। এটাকে "এস্কেপ সিকোয়েন্স" বলা হয়।

"Hello\nworld" => "Hello\nworld"

যে রিটার্ন হয় সেটি একই স্ট্রিং যা আমরা তৈরি করলাম, কিন্তু আপনি দেখতে পাচ্ছেন \n হাইলাইটেড, ইন্ডিকেট করে সেটি একটি এস্কেপ সিকোয়েন্স। আপনি যদি এখন এই স্ট্রিং প্রিন্ট করেন, আপনি দেখবেন লিটারল \n প্রিন্ট হচ্ছে না, বরং একটি আসল নিউলাইন প্রিন্ট হচ্ছে।

puts "Hello\nworld"
=> Hello
world

এটা সিঙ্গেল কোটেড স্ট্রিং-এ কাজ করে না। \n সিকোয়েন্স লিটারল \n- হিসেবে ইন্টারপ্রেট হয়। ডবল কোটেড স্ট্রিং-এ আপনাকে ব্যাকস্ল্যাশ সিম্বল এস্কেপ করতে হবে একই রেজাল্ট পाने।

'\n' => "\\n"

অন্য এস্কেপ সিকোয়েন্সের উদাহরণ যেগুলো একইভাবে কাজ করে: \t, \s এবং \b, যেগুলো রিপ্রেজেন্ট করে একটি ট্যাব, একটি স্পেস এবং একটি ব্যাকস্পেস।

সিঙ্গেল কোট vs এবং ডবল কোট

রুবিতে সিঙ্গেল এবং ডবল কোটেড স্ট্রিং-এর পার্থক্য হলো স্ট্রিং ডেফিনিশনগুলো কীভাবে এস্কেপ সিকোয়েন্স রিপ্রেজেন্ট করে।

  • ডবল কোটেড স্ট্রিং-এ, আপনি এস্কেপ সিকোয়েন্স লিখতে পারেন এবং রুবি তাদের ট্রান্সলেটেড মেইনিং আউটপুট করবে। একটি \n একটি নিউলাইন হয়ে যায়।
  • সিঙ্গেল কোটেড স্ট্রিং-এ যাক, এস্কেপ সিকোয়েন্স এস্কেপ হয় এবং তাদের লিটারল ডেফিনিশন রিটার্ন করে। একটি \n একই থাকে \n।

দুই টাইপ স্ট্রিংর আপনার ইউজ কেস আছে অবশ্যই। সম্ভবত আপনি ডবল কোটেড স্ট্রিং ব্যবহার করবেন এস্কেপ সিকোয়েন্সের সাথে তাদের ট্রান্সলেটেড মেইনিং ব্যবহার করতে, একটি নিউলাইন বা একটি ট্যাব।

সিঙ্গেল কোট উপকারী এস্কেপ সিকোয়েন্স নিজেদের এস্কেপ এড়াতে। তাদের ব্যবহার ডেমন্সট্রেট করতে বা অকস্মাত এস্কেপ সিকোয়েন্স ব্যবহার এড়াতে যেগুলো আপনি ইনটেন্ড করেননি।

puts "Line 1\nLine 2"
=> Line 1
Line 2
puts 'Using a \n we can indicate a newline.'
=> Using a \n we can indicate a newline.

ইন্টারপোলেশন এস্কেপ করা

রুবি স্ট্রিং-এ ইন্টারপোলেশন সাপোর্ট করে। কিন্তু একবার আবার, সব স্ট্রিং ডেফিনিশন সমান নয়। ইন্টারপোলেশন শুধু ডবল কোটেড স্ট্রিং-এ কাজ করে।

নিচের কোড উদাহরণে আমরা দেখতে পাচ্ছি ইন্টারপোলেশন ডবল কোটেড স্ট্রিং-এ কাজ করে, কিন্তু রুবি ইন্টারপোলেশন সিকোয়েন্স সিঙ্গেল কোটেড স্ট্রিং-এ এস্কেপ করে, সেটিকে নিষ্প্রভ করে।

name = "world"
"Hello #{name}" => "Hello world"
'Hello #{name}' => "Hello \#{name}"

এই বিহেভিয়ার প্রায় সব ধরনের স্ট্রিং "ম্যাজিক"-এ প্রযোজ্য। ডবল কোট সাপোর্ট করে, সিঙ্গেল কোট করে না।

স্ট্রিং-এর জন্য পারসেন্ট নোটেশন

রুবিতে পারসেন্ট নোটেশন কিছু পের্ল প্রোগ্রামিং ল্যাঙ্গুয়েজ থেকে ইনস্পায়ারড যা আমাদের কিছু কমন টাইপ ডেফিনিশনের জন্য অনেক শর্টহ্যান্ড দেয়।

সিঙ্গেল এবং ডবল কোটেড স্ট্রিংর জন্য একই বিহেভিয়ার পারসেন্ট নোটেশনের জন্যও প্রযোজ্য।

  • %() এবং %Q() একইভাবে আচরণ করে ডবল কোটেড স্ট্রিং-এর মতো।
  • %q() একইভাবে আচরণ করে সিঙ্গেল কোটেড স্ট্রিং-এর মতো।

পারসেন্ট নোটেশনের সমস্যা হলো আপনাকে এখন প্যারেন্থেসিস ক্যারেক্টার () এস্কেপ করতে হবে কোটের বদলে যখন প্যারেন্থেসিস ব্যালেন্সড নয়।

এর জন্য রুবি আপনাকে অন্যান্য সিম্বল ব্যবহার করার অনুমতি দেয় পারসেন্ট নোটেশনের জন্যও: %[foo], %{foo}, %-foo-, %?foo?, ইত্যাদি। এটা এমনকি %"foo" এবং %'foo' সাপোর্ট করে।

এখানে আমরা দেখতে পাচ্ছি রুবি স্ট্রিংটি আমাদের জন্য এস্কেপ করে পারসেন্ট নোটেশন ব্যবহার করলে।

%("Hello \"world\"!") => "Hello \"world\"!"
# With unbalanced parenthesis
%("Hello world\)!") => "Hello world)!"
# With balanced parenthesis
%("Hello (world)!") => "Hello (world)!"

আবার, নরমাল সিঙ্গেল এবং ডবল কোটেড স্ট্রিংর মতো একই রুল এখানেও প্রযোজ্য। এস্কেপ সিকোয়েন্স এবং ইন্টারপোলেশন ডিফল্টভাবে সিঙ্গেল কোটেড স্ট্রিং-এ এস্কেপ হয়।

name = "world"
%("Hello\n \"#{name}\"!") => "Hello\n \"world\"!"
%q("Hello\n \"#{name}\"!") => "Hello\\n \"\#{name}\"!"
%Q("Hello\n \"#{name}\"!") => "Hello\n \"world\"!"

রেগুলার এক্সপ্রেশনে ক্যারেক্টার এস্কেপ করা

ক্যারেক্টার এস্কেপিং রেগুলার এক্সপ্রেশন-এও কাজ করে। রেগুলার এক্সপ্রেশনে অনেক ক্যারেক্টার তাদের লিটারল ডেফিনিশনের চেয়ে বেশি রিপ্রেজেন্ট করে।

. যেকোনো ক্যারেক্টারের জন্য একটি 와일্ডকার্ড, ব্র্যাকেট [] একটি রেঞ্জ বা সিলেকশন রিপ্রেজেন্ট করে, প্যারেন্থেসিস () একটি এক্সপ্রেশন ম্যাচ করে, ইত্যাদি। তাদের লিটারল ডেফিনিশন ব্যবহার করতে আমরা ব্যাকস্ল্যাশ সিম্বল দিয়ে সেগুলো এস্কেপ করতে পারি।

/Hello \[world\]/ => /Hello \[world\]/
/\[world\]/ =~ "Hello [world]" => 6

আমরা যদি ব্র্যাকেট এস্কেপ না করতাম, সেটি ব্র্যাকেটের মাঝপথের যেকোনো ক্যারেক্টার খুঁজতে এবং ফার্স্ট ম্যাচ পাবে l ক্যারেক্টারে "Hello"-তে পজিশন ৩-এ।

/[world]/ =~ "Hello [world]" => 2 # zero index

ফরোয়ার্ড স্ল্যাশ সিম্বল / এস্কেপ এড়াতে যেটি রেগুলার এক্সপ্রেশন ডিফাইন করতে ব্যবহৃত হয়, আমরা অন্য একটি পারসেন্ট নোটেশন ব্যবহার করতে পারি।

%r{/world/} => /\/world\//

%r{} ব্যবহার করে আমরা একটি রেগুলার এক্সপ্রেশন ডিফাইন করতে পারি যেখানে আমাদের ফরোয়ার্ড স্ল্যাশ এস্কেপ করতে হবে না। রেজাল্টে আমরা দেখতে পাচ্ছি রুবি ফরোয়ার্ড স্ল্যাশ আমাদের জন্য এস্কেপ করে।

লাইন ব্রেক এস্কেপ করা

আগে আমরা স্ট্রিং-এ "নিউলাইন" এস্কেপ সিকোয়েন্স \n এস্কেপ করেছিলাম রুবিতে। আপনি কি জানতেন আপনি রুবি নিজেই একটি লাইন ব্রেক এস্কেপ করতে পারেন?

উদাহরণস্বরূপ, আমাদের একটি খুব লম্বা লাইন আছে একটি মেথড কলের জন্য এবং এটা আমাদের কোড স্টাইল গাইডের ম্যাক্স লাইন লেথ ভাঙছে।

ruby_method_with_many_arguments "Hello world", split: " ", join: "\n"

আমরা আর্গুমেন্টগুলো আলাদা লাইনে রাখতে পারি প্রতিটি লাইন ছোট করার জন্য। এটা কাজ করে যতক্ষণ না আগের লাইন একটি কমা , দিয়ে শেষ হয়, অপারেটর যেন প্লাস সিম্বল +, বা একটি মেথড কলের অংশ হয় প্যারেন্থেসিস () দিয়ে র‍্যাপ করা।

ruby_method_with_many_arguments "Hello world", split: " ", join: "\n"
ruby_method_with_many_arguments(
  "Hello world",
  split: " ",
  join: "\n"
)

যদি বদলে আমরা সকল আর্গুমেন্ট একই ইনডেন্টেশন লেভেলে আলাইন করতে চাই প্যারেন্থেসিস () ছাড়া, আমরা একটি ব্যাকস্ল্যাশ \ ব্যবহার করতে পারি লাইন ব্রেক এস্কেপ করতে।

ruby_method_with_many_arguments \
  my_string, split: " ", join: "\n"

এখানে আমরা আসলে রুবিকে বলছি না নিউলাইন এস্কেপ করতে, বরং সেটি স্টেটমেন্টটি পরবর্তী লাইনে কন্টিনিউ করবে।

স্ট্রিং ডেফিনিশনে লাইন ব্রেক এস্কেপ করা

লাইন এন্ডিং এস্কেপ করা স্ট্রিং ডেফিনিশনের মতো জিনিসের জন্যও কাজ করে। সাধারণত যদি আমাদের একটি মাল্টি-লাইন স্ট্রিং থাকে, আমরা প্লাস সিম্বল + ব্যবহার করতে পারি দুটি লাইনের স্ট্রিং কম্বাইন করতে।

"foo" + "bar" => "foobar"

এটা দুটি লাইনে দুটি স্ট্রিং তৈরি করে এবং তারপর এক স্ট্রিং হিসেবে কম্বাইন করে। তাই আসলে তিনটি স্ট্রিং অবজেক্ট তৈরি হয়।

প্লাস সিম্বল ব্যবহার করার বদলে, আমরা ব্যাকস্ল্যাশ দিয়ে আবার লাইন ব্রেক এস্কেপ করতে পারি।

"foo" \ "bar" => "foobar"

রেজাল্ট একই, নাকি?

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

উপসংহার

রুবি, এবং অন্যান্য প্রোগ্রামিং ল্যাঙ্গুয়েজে ক্যারেক্টার এস্কেপিং খুব কনফিউজিং হতে পারে। হঠাৎ নির্দিষ্ট ক্যারেক্টার কম্বিনেশন ডবল কোটেড স্ট্রিং-এ ভিন্ন মানে পায় সিঙ্গেল কোটেড স্ট্রিং-এ ব্যবহারের তুলনায়।

আশা করি এই ছোট গাইড আপনাকে রুবিতে প্রপারলি ক্যারেক্টার এবং সিকোয়েন্স এস্কেপ করার বুঝতে সাহায্য করেছে। ডবল এবং সিঙ্গেল কোটেড স্ট্রিং-এর পার্থক্য এখানে কী।

স্ট্রিং "ম্যাজিক" এস্কেপ সিকোয়েন্স এবং ইন্টারপোলেশন শুধু ডবল কোটেড স্ট্রিং-এ কাজ করে, সিঙ্গেল কোটেড স্ট্রিং-এ নয়।

রুবি কোডে এস্কেপ করার অন্য উপায়ও আছে। পারসেন্ট নোটেশন আমাদের সাহায্য করে নির্দিষ্ট ক্যারেক্টার সবসময় এস্কেপ করার থেকে বাঁচাতে, স্ট্রিং এবং রেগুলার এক্সপ্রেশনে।

তবে ব্যাকস্ল্যাশও খুব উপকারী মাল্টি-লাইন স্ট্রিং লিখতে এবং একটি রুবি কোড লাইন পরবর্তী লাইনে কন্টিনিউ করতে। কিছুটা আমি খুব বেশি ব্যবহার করি আমার কোড ক্লিন এবং রিডেবল রাখতে।

@AppSignal-এ আমাদের জানান আপনি আরও জানতে চান, বা রুবিতে ক্যারেক্টার এস্কেপিং নিয়ে কোনো স্পেসিফিক প্রশ্ন আছে।

মজার সাইড-নোট: এই পোস্টের জন্য, যেটি মার্কডাউনে লেখা, আমাকে ব্যাকস্ল্যাশ সিম্বল খুব বেশি ব্যবহার করতে হয়েছে। রুবির মতো, মার্কডাউনও নির্দিষ্ট ক্যারেক্টার এস্কেপ করার অনুমতি দেয়। সাধারণত মার্কডাউনে আপনি একটা ব্যাকস্ল্যাশ কোড ব্লকে র‍্যাপ করতে পারেন না কারণ সেটি কোড ব্লককেই এস্কেপ করে। বদলে আমি সেটি একটি স্পেস এস্কেপ করি।

`\` # Doesn't work
`\ ` # Works :)
  1. HTML ক্যারেক্টার এস্কেপিং: রিজার্ভড ক্যারেক্টার সঠিকভাবে দেখানোর পদ্ধতি

  2. জাভাস্ক্রিপ্টে এস্কেপ ক্যারেক্টারস

  3. জাভাস্ক্রিপ্টে একসেন্টযুক্ত ক্যারেক্টরের স্ট্রিং সর্ট করা

  4. C ভাষায় ক্যারেক্টার এবং স্ট্রিং ভিন্ন ফরম্যাটে প্রিন্ট করার প্রোগ্রাম