স্ট্রিং অবজেক্ট

এই নিবন্ধে String অবজেক্ট ব্যাখ্যা করা হয়েছে।

এই ব্যাখ্যাটি বেসিক থেকে অ্যাডভান্সড কৌশল, ইউনিকোড এবং রেগুলার এক্সপ্রেশন সংক্রান্ত ঝামেলা সহ, ধাপে ধাপে এবং সহজভাবে উপস্থাপন করে।

YouTube Video

স্ট্রিং অবজেক্ট

জাভাস্ক্রিপ্টে স্ট্রিং হল প্রতিদিনের ডেভেলপমেন্টে সবচেয়ে বেশি ব্যবহৃত টাইপগুলোর একটি।

প্রিমিটিভ স্ট্রিং এবং স্ট্রিং অবজেক্টের মধ্যে পার্থক্য

প্রিমিটিভ স্ট্রিং ("hello" এর মতো) এবং new String("hello") এর মতো র‍্যাপার অবজেক্ট আলাদা ভাবে আচরণ করে। সাধারণভাবে, আপনাকে প্রিমিটিভ ব্যবহার করা উচিত, অবজেক্ট ফর্ম ব্যবহার করার তেমন প্রয়োজন নেই।

1// Primitive string
2const a = "hello";
3
4// String wrapper object
5const b = new String("hello");
6
7console.log(typeof a); // "string"
8console.log(typeof b); // "object"
9console.log(a === b);  // false — wrapper objects are not strictly equal
  • এই কোডটি প্রিমিটিভ এবং র‍্যাপার অবজেক্টের টাইপের পার্থক্য এবং স্ট্রিক্ট কম্পারিজন কিভাবে আচরণ করে তা দেখায়। অধিকাংশ ক্ষেত্রে, new String() ব্যবহার থেকে বিরত থাকুন এবং প্রিমিটিভ ব্যবহার করুন।

স্ট্রিং তৈরির উপায় (লিটারাল ও টেম্পলেট লিটারাল)

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

1const name = "Alice";
2const age = 30;
3
4// Template literal
5const greeting = `Name: ${name}, Age: ${age + 1}`;
6
7console.log(greeting); // "Name: Alice, Age: 31"
  • টেম্পলেট লিটারাল খুবই সহজপাঠ্য ও মাল্টি-লাইনসহ জটিল স্ট্রিং নির্মাণের জন্য আদর্শ।

সাধারণ মেথডসমূহ (সার্চ ও সাবস্ট্রিং এক্সট্রাকশন)

String অবজেক্টে অনেক মৌলিক মেথড রয়েছে।

 1const text = "Hello, world! Hello again.";
 2
 3// search
 4console.log(text.indexOf("Hello"));       // 0
 5console.log(text.indexOf("Hello", 1));    // 13
 6console.log(text.includes("world"));      // true
 7console.log(text.startsWith("Hello"));    // true
 8console.log(text.endsWith("again."));     // true
 9
10// slice / substring
11console.log(text.slice(7, 12));           // "world"
12console.log(text.substring(7, 12));       // "world"
  • slice এবং substring প্রায় একই, তবে তারা নেগেটিভ ইনডেক্স ভিন্নভাবে পরিচালনা করে। slice নেগেটিভ মানকে শেষে থেকে অবস্থান হিসাবে গণ্য করে। কোনটি ব্যবহার করবেন তা স্পষ্ট থাকুন।

ভাঙা ও জোড়া লাগানো (split / join)

প্রসেসিংয়ের জন্য সাধারণত স্ট্রিংকে অ্যারেতে ভাগ করা হয় এবং শেষে আবার জোড়া লাগানো হয়।

1const csv = "red,green,blue";
2const arr = csv.split(","); // ["red","green","blue"]
3
4console.log(arr);
5console.log(arr.join(" | ")); // "red | green | blue"
  • split দিয়ে স্ট্রিং ভাগ, map বা filter দিয়ে অ্যারে প্রসেস, পরে join দিয়ে আবার একত্র করা—এটি একটি সাধারণ প্যাটার্ন।

রিপ্লেস এবং রেগুলার এক্সপ্রেশন

replace শুধুমাত্র প্রথম মিল পাওয়া অংশটিই পরিবর্তন করে। সবগুলো মিল পরিবর্তন করতে রেগুলার এক্সপ্রেশনে g ফ্ল্যাগ ব্যবহার করুন। রিপ্লেসমেন্ট হিসেবে একটি ফাংশন দিলে ডায়নামিক রিপ্লেসমেন্টও করতে পারেন।

 1const s = "foo 1 foo 2";
 2
 3// replace first only
 4console.log(s.replace("foo", "bar")); // "bar 1 foo 2"
 5
 6// replace all using regex
 7console.log(s.replace(/foo/g, "bar")); // "bar 1 bar 2"
 8
 9// replace with function
10const r = s.replace(/\d+/g, (match) => String(Number(match) * 10));
11console.log(r);    // "foo 10 foo 20"
  • ডায়নামিক রিপ্লেসমেন্টের ফলে ম্যাচ বিশ্লেষণ ও রূপান্তর করার সংক্ষিপ্ত কোড লেখা যায়।

হরফ পরিবর্তন ও স্বাভাবিককরণ (নরমালাইজেশন)

বহুভাষিক সমর্থন এবং তুলনার জন্য, toLowerCase এবং toUpperCase ছাড়াও ইউনিকোড স্বাভাবিকীকরণ (normalize) ও গুরুত্বপূর্ণ। উচ্চারণযুক্ত অক্ষর তুলনার সময় এটি বিশেষভাবে প্রয়োজনীয়।

 1// Case conversion example:
 2// "\u00DF" represents the German letter "ß".
 3// In some locales, converting "ß" to uppercase becomes "SS".
 4// JavaScript follows this behavior.
 5console.log("\u00DF");
 6console.log("\u00DF".toUpperCase()); // "SS"
 7
 8// Unicode normalization example:
 9// "e\u0301" is "e" + a combining acute accent.
10// "\u00e9" is the precomposed character "é".
11// These two look the same but are different code point sequences.
12const a = "e\u0301";
13const b = "\u00e9";
14
15console.log(a === b);   // false: different underlying code points
16console.log(a.normalize() === b.normalize()); // true: normalized to the same form
  • লিগেচার বা কম্বাইনিং ক্যারেক্টারের মতো বিভিন্ন ইউনিকোড রূপ সরাসরি সমান নয়, তাই তুলনা করার আগে অবশ্যই normalize() ব্যবহার করুন।

ইউনিকোড এবং কোড পয়েন্ট (সারোগেট পেয়ার হ্যান্ডলিং)

জাভাস্ক্রিপ্ট স্ট্রিংগুলো UTF-16 কোড ইউনিটের সিকোয়েন্স, তাই ইমোজির মতো কিছু ক্যারেক্টার একটি ক্যারেক্টারের জন্য দুটি ইউনিট নিতে পারে। আসল ক্যারেক্টার ইউনিট পরিচালনার জন্য Array.from, স্প্রেড অপারেটর অথবা for...of ব্যবহার করুন।

 1// Emoji composed with multiple code points:
 2// "\u{1F469}" = woman, "\u{200D}" = Zero Width Joiner (ZWJ),
 3// "\u{1F4BB}" = laptop. Combined, they form a single emoji: 👩‍💻
 4const s = "\u{1F469}\u{200D}\u{1F4BB}";
 5console.log(s);
 6
 7// Length in UTF-16 code units (not actual Unicode characters):
 8// Because this emoji uses surrogate pairs + ZWJ, the length may be > 1.
 9console.log("Length:", s.length);
10
11// Iterate by Unicode code points (ES6 for...of iterates code points):
12// Each iteration gives a full Unicode character, not UTF-16 units.
13for (const ch of s) {
14  console.log(ch);
15}
16
17// Convert to an array of Unicode characters:
18console.log(Array.from(s));
  • length কোড ইউনিটের সংখ্যা দেয়, তাই ইমোজি বা লিগেচার ক্ষেত্রে প্রত্যাশিত সংখ্যা নাও পেতে পারেন। for...of এবং Array.from প্রদর্শিত ক্যারেক্টার (গ্রাফিম ক্লাস্টার) অনুযায়ী কাজ করে, তবে সম্পূর্ণ গ্রাফিম সাপোর্টের জন্য বিশেষায়িত লাইব্রেরি বিবেচনা করুন।

নিরাপদ রেগুলার এক্সপ্রেশন রিপ্লেসমেন্ট (ইউজার ইনপুট ব্যবহারের সময়)

যদি আপনি একটি রেগুলার এক্সপ্রেশনে ব্যবহারকারীর ইনপুট সন্নিবেশ করার সময় সেটি এস্কেপ করতে ভুলে যান, তাহলে এটি অপ্রত্যাশিত আচরণ ও দুর্বলতার কারণ হতে পারে। ইউজার ইনপুট প্যাটার্নে ব্যবহার করার আগে অবশ্যই এস্কেপ করুন।

1function escapeRegex(s) {
2  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3}
4
5const userInput = "a+b";
6const pattern = new RegExp(escapeRegex(userInput), "g");
7console.log("a+b a+b".replace(pattern, "X")); // "X X"
  • ইউজার স্ট্রিং সরাসরি রেগুলার এক্সপ্রেশনে ব্যবহার করবেন না; রেগেক্স তৈরি করার আগে অবশ্যই এস্কেপ করুন।

পারফরম্যান্স টিপস: স্ট্রিং যুক্তকরণ ও টেমপ্লেট

অনেক ছোট স্ট্রিং একসাথে যুক্ত করতে অ্যারেতে রেখে join ব্যবহার করা অধিক কার্যকর। অন্যদিকে, টেমপ্লেট স্ট্রিং অধিকাংশ ক্ষেত্রে সহজপাঠ্য ও যথেষ্ট দ্রুত।

 1// concatenation in loop (less ideal)
 2let s = "";
 3for (let i = 0; i < 1000; i++) {
 4  s += i + ",";
 5}
 6
 7// using array + join (often faster for many pieces)
 8const parts = [];
 9for (let i = 0; i < 1000; i++) {
10  parts.push(i + ",");
11}
12const s2 = parts.join("");
  • আধুনিক জাভাস্ক্রিপ্ট ইঞ্জিন অত্যন্ত অপ্টিমাইজড, তাই কয়েকটি যুক্তকরণে পারফরম্যান্স নিয়ে ভাবার দরকার নেই। তবে, লক্ষাধিক বার যুক্ত করতে হলে join ব্যবহার করা অধিক কার্যকর।

উপকারী ব্যবহারিক কৌশল: প্যাডিং, ট্রিম ও রিপিট

trim, padStart, padEnd, এবং repeat সহজ সুবিধাজনক পদ্ধতি, যা দৈনন্দিন স্ট্রিং প্রক্রিয়াকরণের জন্য বিশেষভাবে উপকারী। এসব পদ্ধতি প্রায়ই ব্যবহার করা হয় যেমন ইনপুট মান ফরম্যাট করা বা আউটপুট ফরম্যাট মানকরণ করার মতো ব্যবহারিক পরিস্থিতিতে।

1console.log("  hello  ".trim());       // "hello"
2console.log("5".padStart(3, "0"));     // "005"
3console.log("x".repeat(5));            // "xxxxx"
  • এই মেথডগুলো ফর্ম ইনপুট স্বাভাবিক করা বা নির্দিষ্ট প্রস্থের আউটপুটের জন্য ব্যবহার করা যায়।

স্ট্রিং তুলনা (লোকেল ভিত্তিক তুলনা)

বিভিন্ন ভাষায় ডিকশনারি অর্ডারে স্ট্রিং তুলনার জন্য localeCompare কার্যকর। আপনি ভাষা ও সংবেদনশীলতা (যেমন, কেস সেনসিটিভিটি) নির্ধারণ করতে পারেন।

1console.log(
2  "\u00E4".localeCompare("z", "de")
3); // may be -1 or other depending on locale
4
5console.log(
6  "a".localeCompare("A", undefined, { sensitivity: "base" })
7); // 0
  • আন্তর্জাতিক তুলনার জন্য localeCompare ব্যবহার করুন এবং উপযুক্ত লোকেল ও অপশন সেট করুন।

ব্যবহারিক উদাহরণ: একটি CSV সারি অবজেক্টে রূপান্তর (কার্যপ্রবাহের উদাহরণ)

একটি সাধারণ ব্যবহার হল, split, trimmap এর সমন্বয়ে একটি CSV সারি অবজেক্টে রূপান্তর। উদ্ধৃত ক্ষেত্র বা জটিল CSV ফাইলে বিশেষ CSV পার্সার ব্যবহার করুন।

 1// simple CSV parse (no quotes handling)
 2function parseCsvLine(line, headers) {
 3  const values = line.split(",").map(v => v.trim());
 4  const obj = {};
 5  headers.forEach((h, i) => obj[h] = values[i] ?? null);
 6  return obj;
 7}
 8
 9const headers = ["name", "age", "city"];
10const line = " Alice , 30 , New York ";
11console.log(parseCsvLine(line, headers));
12// { name: "Alice", age: "30", city: "New York" }
  • এই পদ্ধতি শুধু সাধারণ CSV-তে কার্যকর; কোডেড ফিল্ডে কমা থাকলে এটি কাজ করবে না।

সাধারণ ভুলসমূহ

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

  • new String() ব্যবহার টাইপ চেকিং বা তুলনায় ভুল ফলাফল দিতে পারে। অধিকাংশ ক্ষেত্রে প্রিমিটিভ স্ট্রিং টাইপই যথেষ্ট।
  • ইউনিকোডে একটি দৃশ্যমান অক্ষর একাধিক কোড ইউনিটে গঠিত হতে পারে। সুতরাং, length যেটা ফেরত দেয় তা দৃশ্যমান ক্যারেক্টারের প্রকৃত সংখ্যার সঙ্গে মিল নাও থাকতে পারে।
  • ইউজার ইনপুট রেগুলার এক্সপ্রেশনে ব্যবহার করার আগে অবশ্যই এস্কেপ করুন।
  • String.prototype.replace() ডিফল্টভাবে শুধু প্রথম ম্যাচ রিপ্লেস করে। আপনি যদি সমস্ত উপস্থিতি প্রতিস্থাপন করতে চান, তাহলে আপনার রেগুলার এক্সপ্রেশনে /g ফ্ল্যাগ ব্যবহার করুন।
  • স্ট্রিং অপরিবর্তনীয়, তাই প্রত্যেক অপারেশন একটি নতুন স্ট্রিং ফেরত দেয়। ফেরত পাওয়া মান অবশ্যই অ্যাসাইন করা জরুরি।

সারসংক্ষেপ

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

আপনি আমাদের ইউটিউব চ্যানেলে ভিজ্যুয়াল স্টুডিও কোড ব্যবহার করে উপরের নিবন্ধটি অনুসরণ করতে পারেন। দয়া করে ইউটিউব চ্যানেলটিও দেখুন।

YouTube Video