Java Regular Expressions (Regex) এবং Functional Programming দুটি পৃথক ধারণা, তবে Java 8+ এর মাধ্যমে Functional Programming এর সুবিধাগুলি ব্যবহার করে Regex এর কাজকে আরও আরও কার্যকরী এবং সংক্ষিপ্ত করা সম্ভব হয়েছে। Java 8 এর পরে আমরা নতুন Stream API, Lambda Expressions, এবং Method References এর মতো বৈশিষ্ট্যগুলি পেয়েছি যা আমাদের কোডিংকে আরও আধুনিক এবং কার্যকরী করেছে।
এখানে আমরা Regex এর ব্যবহার এবং Functional Programming এর ধারণা একসাথে দেখব, এবং দেখব কিভাবে Java 8+ এর বৈশিষ্ট্যগুলি Regex প্রসেসিংকে আরও সুন্দর এবং কমপ্যাক্ট করে তোলে।
Java তে Regex ব্যবহৃত হয় টেক্সটের মধ্যে নির্দিষ্ট প্যাটার্ন খুঁজে বের করার জন্য। Java তে Regex ব্যবহার করতে java.util.regex.Pattern
এবং java.util.regex.Matcher
ক্লাসগুলি ব্যবহৃত হয়।
Pattern.compile(String regex)
: একটি নির্দিষ্ট Regex প্যাটার্ন কম্পাইল করে।Matcher.matches()
: প্যাটার্নটি স্ট্রিংয়ের পুরো অংশের সাথে মেলে কি না তা পরীক্ষা করে।Matcher.find()
: প্যাটার্নটি স্ট্রিংয়ের কোনো অংশের সাথে মেলে কি না তা পরীক্ষা করে।Matcher.group()
: একটি মেলে পাওয়া অংশ বা গ্রুপ ফেরত দেয়।Java 8 এর পরে, Functional Programming ধারণাটি Java তে অধিক জনপ্রিয়তা পেয়েছে। এতে Streams, Lambda Expressions, এবং Method References এর মাধ্যমে কমপ্যাক্ট এবং পারফরম্যান্সে দক্ষ কোড লেখা সম্ভব হয়েছে।
Java 8 এর Streams এবং Lambda Expressions এর মাধ্যমে আপনি Regex ব্যবহার করে অনেক কার্যক্রম খুব সহজে এবং কার্যকরভাবে করতে পারেন। যেমন, একটি স্ট্রিংয়ের মধ্যে নির্দিষ্ট প্যাটার্ন খুঁজে বের করা এবং সেই সমস্ত প্যাটার্নের উপরে কিছু অপারেশন প্রয়োগ করা।
ধরা যাক, আমাদের একটি লিস্ট আছে স্ট্রিংয়ের, এবং আমরা এই স্ট্রিংগুলো থেকে শুধুমাত্র এমন স্ট্রিংগুলো বের করতে চাই যা একটি নির্দিষ্ট Regex প্যাটার্নের সাথে মেলে। আমরা Streams এবং Lambda Expressions ব্যবহার করে এটা করব।
import java.util.*;
import java.util.regex.*;
import java.util.stream.*;
public class RegexWithFunctionalProgramming {
public static void main(String[] args) {
// List of strings (can be from a log file, user input, etc.)
List<String> data = Arrays.asList(
"user1@example.com",
"invalid-email",
"contact@company.org",
"hello world",
"user2@domain.com"
);
// Regex pattern for matching email addresses
String emailPattern = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$";
// Stream to filter emails using Regex pattern
List<String> validEmails = data.stream()
.filter(s -> Pattern.matches(emailPattern, s)) // Filtering using regex pattern
.collect(Collectors.toList()); // Collect the valid emails
// Print valid email addresses
validEmails.forEach(System.out::println);
}
}
user1@example.com
contact@company.org
user2@domain.com
Pattern.matches(emailPattern, s)
: এই প্যাটার্নটি ব্যবহার করা হয়েছে যাতে স্ট্রিং s
যদি ইমেইল ঠিকানার ফরম্যাটে হয় তবে তা মেলে।.filter()
মেথডের মাধ্যমে আমরা স্ট্রিংগুলির মধ্যে ইমেইল ঠিকানাগুলি ফিল্টার করেছি এবং .collect()
এর মাধ্যমে সেগুলিকে একটি লিস্টে সন্নিবেশিত করেছি।এখানে আমরা Regex এবং Functional Programming এর আরও একটি ব্যবহার দেখাবো যেখানে আমরা একটি স্ট্রিংয়ের মধ্যে প্যাটার্ন অনুসারে কিছু অংশ ফিল্টার করব এবং পরিবর্তন (transformation) করব।
import java.util.*;
import java.util.regex.*;
import java.util.stream.*;
public class ExtractDatesFromLogs {
public static void main(String[] args) {
// Sample log data
List<String> logs = Arrays.asList(
"2024-12-23 10:30:45 INFO Log message 1",
"2024-12-23 11:45:50 ERROR Log message 2",
"2024-12-23 12:15:10 WARN Log message 3",
"2024-12-23 13:00:00 INFO Log message 4"
);
// Regex pattern for extracting date (YYYY-MM-DD format)
String datePattern = "^\\d{4}-\\d{2}-\\d{2}";
// Extracting dates using stream and regex
List<String> extractedDates = logs.stream()
.filter(log -> log.matches(datePattern)) // Filter logs matching the date pattern
.map(log -> log.substring(0, 10)) // Extract only the date part
.collect(Collectors.toList()); // Collect the extracted dates
// Print the extracted dates
extractedDates.forEach(System.out::println);
}
}
2024-12-23
2024-12-23
2024-12-23
2024-12-23
log.matches(datePattern)
: এখানে আমরা একটি লোগের তারিখ অংশের জন্য একটি regex pattern ব্যবহার করছি যা YYYY-MM-DD
ফরম্যাটে মেলে।map(log -> log.substring(0, 10))
: এই লাইনটি লগের প্রথম ১০টি ক্যারেক্টার (যেটি তারিখ অংশ) বের করার জন্য ব্যবহার করা হয়েছে।ধরা যাক, আমাদের লগ ফাইলের মধ্যে থেকে ERROR লেভেল এর ইনফরমেশন বের করতে হবে, এবং তাছাড়া সেই ইনফরমেশন গুলো থেকে method name এবং error message আলাদা করে বের করতে হবে।
import java.util.*;
import java.util.regex.*;
import java.util.stream.*;
public class RegexWithLogFile {
public static void main(String[] args) {
// Sample log data
List<String> logs = Arrays.asList(
"2024-12-23 10:30:45 ERROR MethodX: NullPointerException",
"2024-12-23 10:32:50 INFO MethodY: Process started",
"2024-12-23 10:34:55 ERROR MethodZ: ArrayIndexOutOfBoundsException",
"2024-12-23 10:35:00 WARN MethodA: Deprecated method usage"
);
// Regex pattern for extracting ERROR logs and method + error message
String errorPattern = "ERROR (\\w+): (.+)";
// Extracting ERROR logs and splitting into method name and error message
logs.stream()
.filter(log -> log.matches(".*ERROR.*")) // Filter ERROR logs
.map(log -> {
Pattern p = Pattern.compile(errorPattern);
Matcher m = p.matcher(log);
if (m.find()) {
return "Method: " + m.group(1) + ", Error: " + m.group(2);
}
return "";
})
.filter(result -> !result.isEmpty()) // Remove empty results
.forEach(System.out::println);
}
}
Method: MethodX, Error: NullPointerException
Method: MethodZ, Error: ArrayIndexOutOfBoundsException
filter(log -> log.matches(".*ERROR.*"))
: এখানে আমরা শুধুমাত্র ERROR
লেভেল লোগ গুলি ফিল্টার করছি।map(log -> {...})
: পরে Regex এর মাধ্যমে আমরা method name এবং error message আলাদা করেছি।Java 8 এ Lambda Expressions এবং Streams API পIntroduced, যা কোড লেখার পদ্ধতিকে আরও কার্যকর এবং সংক্ষিপ্ত করে তোলে। Lambda expressions ব্যবহার করে, আপনি functional programming ধারণা Java তে প্রয়োগ করতে পারেন, এবং Regex এর সাথে একত্রে ব্যবহার করে আপনি আরও সংক্ষিপ্ত এবং কার্যকরী কোড তৈরি করতে পারেন।
এখানে আমরা Lambda Expressions এবং Regex এর Integration কিভাবে করা যায়, তা দেখব।
Lambda expression হল একটি ছোট আকারের ফাংশন যা method implementation ছাড়া প্যারামিটার গ্রহণ করে এবং একটি কার্যকরী মান ফেরত দেয়। এটি Functional Interface এর সাথে কাজ করে।
Syntax:
(parameters) -> expression
উদাহরণ:
(int x, int y) -> x + y
এটি একটি Functional Interface
এর মেথড apply(int x, int y)
কে বাস্তবায়িত করবে।
Regex ব্যবহার করে আপনি স্ট্রিং ম্যানিপুলেশন, ফিল্টারিং, এবং প্যাটার্ন ম্যাচিং কাজ করতে পারেন, এবং যখন আপনি Lambda expressions এর সাথে এটি ইন্টিগ্রেট করেন, তখন আপনি আরও দ্রুত এবং সংক্ষিপ্ত কোড লিখতে পারবেন।
Lambda expressions ব্যবহার করে স্ট্রিংয়ের মধ্যে regex matching করতে পারে, যেটি প্রথাগত loop বা for-each এর তুলনায় সংক্ষিপ্ত এবং পরিষ্কার। এখানে দেখানো হলো কীভাবে Streams API এবং Lambda expressions এর সাথে Regex ব্যবহার করা যায়।
ধরা যাক, আমাদের একটি List of Strings আছে এবং আমরা সেই স্ট্রিংগুলির মধ্যে শুধুমাত্র যেগুলো একটি নির্দিষ্ট regex pattern মেলে তা ফিল্টার করতে চাই।
import java.util.*;
import java.util.regex.*;
import java.util.stream.*;
public class LambdaRegexExample {
public static void main(String[] args) {
List<String> strings = Arrays.asList("apple", "banana", "cherry", "apricot", "mango");
// Define regex pattern for words starting with 'a'
String pattern = "^a.*";
// Use Stream and Lambda Expression to filter strings
List<String> filteredStrings = strings.stream()
.filter(s -> s.matches(pattern)) // Lambda expression for regex matching
.collect(Collectors.toList());
// Print the filtered result
filteredStrings.forEach(System.out::println);
}
}
apple
apricot
s -> s.matches(pattern)
এখানে matches()
method ব্যবহার করা হয়েছে যেটি Regex প্যাটার্নের সাথে স্ট্রিং ম্যাচিং চেক করে। এটি একটি functional interface হিসেবে কাজ করে এবং স্ট্রিং ফিল্টার করার জন্য ব্যবহার করা হয়েছে।strings.stream()
ব্যবহার করে স্ট্রিংগুলির একটি স্ট্রিম তৈরি করা হয়েছে এবং তারপর .filter()
ব্যবহার করে শুধুমাত্র সেই স্ট্রিংগুলোকে ফিল্টার করা হয়েছে যেগুলোর সাথে regex প্যাটার্ন মেলে।একটি সাধারণ ব্যবহার হতে পারে regex substitution (অথবা রূপান্তর)। আমরা Lambda expression ব্যবহার করে স্ট্রিংয়ের মধ্যে substitution করতে পারি, যেখানে regex প্যাটার্নের মাধ্যমে এক বা একাধিক অংশ পরিবর্তন করা হবে।
ধরা যাক, আমাদের একটি List of Strings রয়েছে এবং আমরা সমস্ত digits (সংখ্যা) গুলোকে একটি নির্দিষ্ট character দিয়ে প্রতিস্থাপন করতে চাই।
import java.util.*;
import java.util.regex.*;
import java.util.stream.*;
public class RegexSubstitutionLambda {
public static void main(String[] args) {
List<String> strings = Arrays.asList("hello123", "world456", "java789");
// Define regex pattern for digits
String pattern = "\\d+";
// Replace digits with '#' using Stream and Lambda
List<String> substitutedStrings = strings.stream()
.map(s -> s.replaceAll(pattern, "#")) // Lambda expression for substitution
.collect(Collectors.toList());
// Print the substituted result
substitutedStrings.forEach(System.out::println);
}
}
hello#
world#
java#
s -> s.replaceAll(pattern, "#")
এখানে replaceAll()
মেথড ব্যবহার করা হয়েছে যা স্ট্রিংয়ের মধ্যে সংখ্যাগুলোকে #
দিয়ে প্রতিস্থাপন করেছে। এটি Lambda expression এর মাধ্যমে প্রতিটি স্ট্রিংয়ের উপর প্রয়োগ করা হয়েছে।এখন একটি আরও উন্নত উদাহরণ দেখি যেখানে আমরা stream এবং regex এর সাথে আরও জটিল Lambda expressions ব্যবহার করি।
import java.util.*;
import java.util.regex.*;
import java.util.stream.*;
public class ComplexLambdaRegexExample {
public static void main(String[] args) {
List<String> strings = Arrays.asList("apple123", "banana456", "apricot789", "grape101");
// Define regex pattern for strings containing digits
String pattern = ".*\\d+.*";
// Use Stream, Lambda Expression, and Regex to filter and transform
List<String> transformedStrings = strings.stream()
.filter(s -> s.matches(pattern)) // Filter strings with digits using regex
.map(s -> s.toUpperCase()) // Convert matched strings to uppercase
.collect(Collectors.toList());
// Print the transformed result
transformedStrings.forEach(System.out::println);
}
}
APPLE123
BANANA456
APRICOT789
GRAPE101
s -> s.matches(pattern)
এবং s -> s.toUpperCase()
—এখানে প্রথমে regex matching এর মাধ্যমে সঠিক স্ট্রিং নির্বাচন করা হয়েছে এবং তারপর uppercase রূপান্তর করা হয়েছে।.filter()
মেথডটি regex প্যাটার্নের সাথে মিলে এমন স্ট্রিং ফিল্টার করে এবং .map()
মেথডটি প্রত্যেকটি স্ট্রিংকে uppercase রূপে রূপান্তর করে।Pattern.compile()
ব্যবহার করুন এবং তারপর ব্যবহার করুন। এটি Regex প্যাটার্নের কম্পাইল করার খরচ কমাবে।Lambda Expressions এবং Streams API এর সাথে Regex ইন্টিগ্রেট করে আপনি আরও সংক্ষিপ্ত, পরিষ্কার এবং কার্যকর কোড লিখতে পারেন। এই দুটি শক্তিশালী ফিচারের সংমিশ্রণ আপনার স্ট্রিং ম্যানিপুলেশন এবং প্যাটার্ন ম্যাচিংয়ের কাজকে দ্রুততর এবং আরও উন্নত করে তুলবে। তবে, performance optimization এর জন্য regex কম্পাইলেশন এবং প্যাটার্নের ব্যবহারের উপর নজর রাখা উচিত।
Java 8-এ Streams API এবং Regular Expressions (Regex) ব্যবহারের মাধ্যমে আপনি ডেটা প্রসেসিং এবং প্যাটার্ন ম্যাচিংকে আরও শক্তিশালী, সহজ এবং কার্যকরীভাবে একত্রিত করতে পারেন। Streams API এর মাধ্যমে আপনি ডেটাকে ফিল্টার, ম্যানিপুলেট এবং ট্রান্সফর্ম করতে পারেন, এবং Regex ব্যবহার করে আপনি ডেটার মধ্যে নির্দিষ্ট প্যাটার্ন বা শর্ত মিলিয়ে কাজ করতে পারেন।
এই দুটি টুল একসাথে ব্যবহারের মাধ্যমে আপনি জটিল ডেটা প্রসেসিং টাস্কগুলো আরও সহজে সম্পন্ন করতে পারবেন। আসুন দেখি কীভাবে Streams API এবং Regex একসাথে ব্যবহার করা যায়।
ধরা যাক, আমাদের একটি লিস্ট আছে যেটিতে স্ট্রিং রয়েছে, এবং আমরা সেই স্ট্রিংগুলো ফিল্টার করতে চাই যেগুলোর মধ্যে একটি নির্দিষ্ট প্যাটার্ন (যেমন, একটি ইমেইল ঠিকানা বা ফোন নম্বর) রয়েছে।
ধরা যাক, আমাদের একটি লিস্ট আছে যার মধ্যে বিভিন্ন স্ট্রিং রয়েছে, এবং আমরা Regex ব্যবহার করে ইমেইল অ্যাড্রেস এবং ফোন নম্বর খুঁজে বের করব।
import java.util.*;
import java.util.regex.*;
import java.util.stream.*;
public class StreamsAndRegexExample {
public static void main(String[] args) {
// Sample list of strings
List<String> data = Arrays.asList(
"john.doe@example.com",
"My phone number is +1-800-555-1234",
"hello world",
"Contact us at support@company.com",
"12345"
);
// Regex for matching email addresses
String emailRegex = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$";
Pattern emailPattern = Pattern.compile(emailRegex);
// Regex for matching phone numbers
String phoneRegex = "\\+\\d{1,3}-\\d{1,4}-\\d{1,4}-\\d{1,4}";
Pattern phonePattern = Pattern.compile(phoneRegex);
// Using Streams API to filter and match patterns
List<String> emails = data.stream()
.filter(s -> emailPattern.matcher(s).matches()) // Match emails
.collect(Collectors.toList());
List<String> phoneNumbers = data.stream()
.filter(s -> phonePattern.matcher(s).matches()) // Match phone numbers
.collect(Collectors.toList());
// Print the results
System.out.println("Emails found:");
emails.forEach(System.out::println);
System.out.println("\nPhone Numbers found:");
phoneNumbers.forEach(System.out::println);
}
}
data.stream()
: data
লিস্ট থেকে একটি স্ট্রিম তৈরি করা হয়েছে।.filter()
: প্রতিটি স্ট্রিং ফিল্টার করা হচ্ছে একটি শর্তের ভিত্তিতে।.collect(Collectors.toList())
: ফিল্টার হওয়া স্ট্রিংগুলিকে একটি নতুন লিস্টে সংগ্রহ করা হচ্ছে।emailPattern.matcher(s).matches()
: এটি চেক করে যে স্ট্রিংটি ইমেইল প্যাটার্নের সাথে মেলে কি না।phonePattern.matcher(s).matches()
: এটি চেক করে যে স্ট্রিংটি ফোন নম্বর প্যাটার্নের সাথে মেলে কি না।Emails found:
john.doe@example.com
Contact us at support@company.com
Phone Numbers found:
+1-800-555-1234
Java Reflection Package (java.lang.reflect
) এবং Functional Interfaces (যেমন Predicate
, Function
, Consumer
, Supplier
) এর মাধ্যমে Regex ব্যবহারের ধারণা একটি অত্যন্ত শক্তিশালী কৌশল, যেখানে আপনি Functional Programming এবং Regex Matching কে একত্রিত করেন। এটি কোডের পুনঃব্যবহারযোগ্যতা এবং পরিষ্কারতাকে বাড়াতে সাহায্য করে, কারণ আপনি রেগুলার এক্সপ্রেশন (Regex) এবং ফাংশনাল ইন্টারফেস ব্যবহার করে বিভিন্ন স্ট্রিং ম্যানিপুলেশন বা প্যাটার্ন ম্যাচিং কার্যক্রমকে আরও সহজ এবং কার্যকরীভাবে বাস্তবায়িত করতে পারেন।
ফাংশনাল ইন্টারফেস এমন ইন্টারফেস যা শুধুমাত্র একটি অ্যাবস্ট্র্যাক্ট মেথড থাকে। Java-তে একটি Functional Interface ব্যবহার করা হয় যেসব ক্ষেত্রে আপনি lambda expressions বা method references ব্যবহার করতে চান। কিছু উদাহরণ হলো:
Predicate<T>
: একটি বুলিয়ান মান প্রদান করে, যা সাধারণত একটি শর্ত চেক করার জন্য ব্যবহৃত হয়।Function<T, R>
: একটি ইনপুট অ্যারগুমেন্ট গ্রহণ করে এবং একটি আউটপুট প্রদান করে।Consumer<T>
: ইনপুট নেয় কিন্তু আউটপুট প্রদান করে না।আপনি Functional Interfaces ব্যবহার করে Regex Matching করতে পারেন, যেমন:
Predicate
দিয়ে আপনি স্ট্রিংয়ে নির্দিষ্ট প্যাটার্ন মিলছে কিনা তা চেক করতে পারেন।Function
দিয়ে স্ট্রিংয়ের উপর রেগুলার এক্সপ্রেশন প্রয়োগ করতে এবং ফলাফল রিটার্ন করতে পারেন।Predicate
একটি ফাংশনাল ইন্টারফেস, যা একটি শর্ত নির্ধারণ করে এবং সে শর্তটি যদি পূর্ণ হয়, তবে true
রিটার্ন করে।
এখানে আমরা Predicate
ব্যবহার করে একটি স্ট্রিংয়ের মধ্যে একটি নির্দিষ্ট প্যাটার্ন যাচাই করব:
import java.util.function.Predicate;
import java.util.regex.*;
public class RegexWithPredicate {
public static void main(String[] args) {
// Regular expression to check if the string is a valid phone number
String phoneNumber = "+1-800-555-1234";
Predicate<String> isValidPhoneNumber = s -> s.matches("^\\+\\d{1,3}-\\d{1,4}-\\d{1,4}-\\d{1,4}$");
if (isValidPhoneNumber.test(phoneNumber)) {
System.out.println("Valid phone number: " + phoneNumber);
} else {
System.out.println("Invalid phone number: " + phoneNumber);
}
}
}
Predicate<String> isValidPhoneNumber
: এখানে একটি Predicate
ব্যবহার করা হয়েছে যা স্ট্রিংটি একটি ফোন নম্বর ফরম্যাটের সাথে মেলে কিনা তা যাচাই করে। s.matches(...)
পদ্ধতি ব্যবহার করে এটি রেগুলার এক্সপ্রেশন পরীক্ষা করছে।isValidPhoneNumber.test(phoneNumber)
: test()
মেথডটি প্যাটার্নের সাথে স্ট্রিং মিলছে কিনা তা যাচাই করবে এবং true
বা false
রিটার্ন করবে।Valid phone number: +1-800-555-1234
আপনি Function<T, R>
ফাংশনাল ইন্টারফেস ব্যবহার করে একটি ইনপুট স্ট্রিং গ্রহণ করতে পারেন এবং রেগুলার এক্সপ্রেশন ব্যবহার করে আউটপুট ফলাফল প্রদান করতে পারেন। নিচে একটি উদাহরণ দেওয়া হলো যেখানে রেগুলার এক্সপ্রেশন দিয়ে একটি স্ট্রিংয়ের সমস্ত ডিজিট বের করা হচ্ছে।
import java.util.function.Function;
import java.util.regex.*;
public class RegexWithFunction {
public static void main(String[] args) {
// Regex to extract digits from a string
String input = "My phone number is 123-456-7890.";
Function<String, String> extractDigits = s -> {
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher(s);
StringBuilder digits = new StringBuilder();
while (matcher.find()) {
digits.append(matcher.group());
}
return digits.toString();
};
String digits = extractDigits.apply(input);
System.out.println("Extracted digits: " + digits);
}
}
Function<String, String> extractDigits
: এখানে একটি Function
ব্যবহার করা হয়েছে, যা স্ট্রিং ইনপুট গ্রহণ করে এবং রেগুলার এক্সপ্রেশন ব্যবহার করে সমস্ত ডিজিট বের করে।matcher.find()
: এটি স্ট্রিং থেকে সমস্ত ডিজিট খুঁজে বের করে এবং group()
মেথডের মাধ্যমে তা স্টোর করে।Extracted digits: 1234567890
Consumer
ফাংশনাল ইন্টারফেস একটি ইনপুট নেয় এবং কিছু অপারেশন সম্পাদন করে, তবে কোন রিটার্ন ভ্যালু দেয় না। এটি সাধারণত কিছু প্রভাব ফেলতে ব্যবহৃত হয়, যেমন লগিং, বা স্ট্রিং ম্যানিপুলেশন।
import java.util.function.Consumer;
import java.util.regex.*;
public class RegexWithConsumer {
public static void main(String[] args) {
// Regex to print out each match from a string
String input = "I have 2 apples and 3 oranges.";
Consumer<String> printMatches = s -> {
Pattern pattern = Pattern.compile("\\d+"); // Match digits
Matcher matcher = pattern.matcher(s);
while (matcher.find()) {
System.out.println("Found number: " + matcher.group());
}
};
// Apply the consumer to the input
printMatches.accept(input);
}
}
Consumer<String> printMatches
: এটি একটি Consumer
ফাংশনাল ইন্টারফেস, যা স্ট্রিং ইনপুট নেয় এবং স্ট্রিংয়ের মধ্যে ডিজিট খুঁজে বের করে প্রিন্ট করে।matcher.find()
: এটি স্ট্রিং থেকে সমস্ত ডিজিট খুঁজে বের করে এবং group()
মেথডের মাধ্যমে তা প্রিন্ট করে।Found number: 2
Found number: 3
Predicate
ব্যবহার করে আপনি স্ট্রিংয়ের সাথে প্যাটার্ন ম্যাচিং করতে পারেন এবং একটি শর্ত চেক করতে পারেন।Function
ব্যবহার করে আপনি স্ট্রিং ইনপুট নিয়ে কিছু রেগুলার এক্সপ্রেশন প্রক্রিয়া করতে পারেন এবং ফলাফল আউটপুট হিসেবে ফিরিয়ে দিতে পারেন।Consumer
ব্যবহার করে আপনি স্ট্রিংয়ের উপর কোনো কার্য সম্পাদন করতে পারেন, যেমন প্যাটার্ন খুঁজে বের করা এবং তা প্রিন্ট করা।ফাংশনাল ইন্টারফেস এবং রেগুলার এক্সপ্রেশন ব্যবহার করে আপনি কোডটিকে আরও কমপ্যাক্ট এবং রক্ষণাবেক্ষণযোগ্য করতে পারবেন।
Java 8 এ অনেক নতুন functional programming ফিচার যুক্ত করা হয়েছে, যেমন lambda expressions, streams, default methods, Optional এবং আরও অনেক কিছু। এসব ফিচারের সাথে regular expressions (Regex) ব্যবহারের মাধ্যমে কার্যকারিতা আরও উন্নত করা যেতে পারে। নিচে কিছু Java 8 এর advanced features এবং Regex এর integration কিভাবে করা যেতে পারে, তা আলোচনা করা হয়েছে।
Lambda expressions Java 8 এ একটি গুরুত্বপূর্ণ বৈশিষ্ট্য যা আপনাকে ছোট ফাংশনগুলি লিখতে সাহায্য করে। আপনি lambda expressions ব্যবহার করে Regex matching এবং filtering এর মতো কাজ সহজেই করতে পারেন।
ধরা যাক, একটি তালিকা আছে যেটিতে বিভিন্ন স্ট্রিং রয়েছে এবং আপনি চাইছেন Regex ব্যবহার করে এই স্ট্রিং গুলোর মধ্যে কিছু বিশেষ প্যাটার্ন খুঁজে বের করতে।
import java.util.*;
import java.util.regex.*;
import java.util.stream.*;
public class RegexLambdaExample {
public static void main(String[] args) {
List<String> strings = Arrays.asList("apple", "banana", "123", "cherry", "abc123");
// Regex pattern to match words containing numbers
String pattern = ".*\\d+.*";
// Using lambda to filter and match regex
strings.stream()
.filter(s -> s.matches(pattern)) // Lambda expression for regex matching
.forEach(System.out::println);
}
}
123
abc123
stream()
মেথডটি একটি stream তৈরি করে যা পরবর্তীতে filter()
মেথডের মাধ্যমে প্যাটার্নের সাথে মেলে এমন স্ট্রিং খুঁজে বের করে।matches()
মেথডটি স্ট্রিংয়ের সাথে Regex প্যাটার্ন মেলানোর জন্য ব্যবহৃত হয়।s -> s.matches(pattern)
স্ট্রিংগুলো ফিল্টার করার জন্য ব্যবহার করা হয়েছে।Streams API Java 8 এর অন্যতম গুরুত্বপূর্ণ বৈশিষ্ট্য, যা আপনাকে ডেটার উপর কার্যকরীভাবে কাজ করার সুযোগ দেয়। Regex এর সাথে Streams API ব্যবহার করে আপনি বড় ডেটাসেটের উপর কার্যকরীভাবে Regex মেলানোর কাজ করতে পারেন।
import java.util.*;
import java.util.regex.*;
import java.util.stream.*;
public class RegexStreamsExample {
public static void main(String[] args) {
List<String> strings = Arrays.asList("apple", "banana", "123", "cherry", "abc123");
// Regex pattern to match strings starting with 'a'
String pattern = "^a.*";
// Using Streams API and Regex to filter strings
List<String> result = strings.stream()
.filter(s -> s.matches(pattern)) // Matching regex
.collect(Collectors.toList());
result.forEach(System.out::println);
}
}
apple
abc123
stream()
দ্বারা স্ট্রিং তালিকাটি স্ট্রিমে রূপান্তরিত হয়েছে।filter()
মেথডে Regex matching ব্যবহার করা হয়েছে s.matches(pattern)
।Optional ক্লাসটি Java 8 এর একটি ফিচার যা নাল ভ্যালু প্রতিরোধে সহায়ক। যখন আপনি একটি স্ট্রিংয়ের ওপর Regex validation করতে চান, তখন Optional
ব্যবহার করে আপনি সেফভাবে null checks করতে পারেন।
import java.util.Optional;
import java.util.regex.*;
public class RegexOptionalExample {
public static void main(String[] args) {
// Regex pattern to validate email
String pattern = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$";
// Sample email
String email = "example@example.com";
// Using Optional to handle null safely
Optional<String> optionalEmail = Optional.ofNullable(email);
boolean isValidEmail = optionalEmail
.filter(e -> e.matches(pattern)) // Regex validation
.isPresent(); // Check if valid email exists
if (isValidEmail) {
System.out.println("Valid email address.");
} else {
System.out.println("Invalid email address.");
}
}
}
Valid email address.
Optional.ofNullable(email)
ব্যবহার করে একটি Optional
অবজেক্ট তৈরি করা হয়েছে।filter()
মেথডের মাধ্যমে Regex ব্যবহার করে ইমেইল ভ্যালিডেশন করা হয়েছে।email
প্যাটার্নের সাথে মিলে যায়, তবে isPresent()
true
ফেরত দেবে, এবং ইমেইলটি বৈধ বলে চিহ্নিত হবে।Java 8 এ default methods ব্যবহার করে আপনি ইন্টারফেসে মেথডের ডিফল্ট বাস্তবায়ন প্রদান করতে পারেন। আপনি Regex সম্পর্কিত কাজগুলো ইন্টারফেসে ডিফাইন করে default methods ব্যবহার করে কোড পুনরায় ব্যবহারযোগ্য করতে পারেন।
import java.util.regex.*;
interface RegexProcessor {
// Default method for regex matching
default boolean matches(String text, String pattern) {
return text.matches(pattern);
}
}
public class RegexWithDefaultMethod implements RegexProcessor {
public static void main(String[] args) {
RegexWithDefaultMethod processor = new RegexWithDefaultMethod();
String text = "hello123";
String pattern = "\\w+\\d+";
// Using default method to check pattern matching
if (processor.matches(text, pattern)) {
System.out.println("Pattern matched!");
} else {
System.out.println("Pattern not matched.");
}
}
}
Pattern matched!
matches()
ইন্টারফেসে ডিফাইন করা হয়েছে এবং এটি একটি প্যাটার্নের সাথে স্ট্রিং ম্যাচ করে।RegexWithDefaultMethod
এ আমরা এই ডিফল্ট মেথডটি ব্যবহার করেছি।Java 8 এ Method References ব্যবহার করে আপনি মেথড কলকে আরও সংক্ষিপ্ত এবং পাঠযোগ্য করতে পারেন। Regex এর ক্ষেত্রে, আপনি method references ব্যবহার করে কিছু প্যাটার্ন মেলানোর কাজ আরও সহজভাবে করতে পারেন।
import java.util.*;
import java.util.regex.*;
public class MethodReferenceExample {
public static void main(String[] args) {
List<String> strings = Arrays.asList("apple", "banana", "123", "cherry", "abc123");
// Regex pattern to match words containing digits
String pattern = ".*\\d+.*";
// Using method reference to filter and match regex
strings.stream()
.filter(MethodReferenceExample::isMatching) // Method reference
.forEach(System.out::println);
}
// Method to check if the string matches the pattern
public static boolean isMatching(String str) {
return str.matches(".*\\d+.*");
}
}
123
abc123
MethodReferenceExample::isMatching
এই মেথড রেফারেন্সটি filter()
মেথডে ব্যবহার করা হয়েছে, যা Regex matching করতে সাহায্য করে।Java 8 এর advanced features যেমন lambda expressions, streams, default methods, Optional, এবং method references Regex এর সাথে ইন্টিগ্রেট করে কোডকে আরও কার্যকরী, সংক্ষিপ্ত এবং পরিষ্কার করে তোলে। এসব ফিচার Regex-এর কার্যকারিতা এবং কোড পুনরায় ব্যবহারের জন্য গুরুত্বপূর্ণ এবং বড় ডেটাসেট বা জটিল টেক্সট ম্যানিপুলেশনে performance উন্নত করতে সাহায্য করে।
Read more