Java Regex এবং Functional Programming (Java 8+)

Java Technologies - জাভা রেজেক্স (Java Regex)
95
95

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 প্রসেসিংকে আরও সুন্দর এবং কমপ্যাক্ট করে তোলে।


1. Java Regex (Regular Expressions) Overview:

Java তে Regex ব্যবহৃত হয় টেক্সটের মধ্যে নির্দিষ্ট প্যাটার্ন খুঁজে বের করার জন্য। Java তে Regex ব্যবহার করতে java.util.regex.Pattern এবং java.util.regex.Matcher ক্লাসগুলি ব্যবহৃত হয়।

Regex ব্যবহার করার জন্য প্রাথমিক মেথডগুলি:

  • Pattern.compile(String regex): একটি নির্দিষ্ট Regex প্যাটার্ন কম্পাইল করে।
  • Matcher.matches(): প্যাটার্নটি স্ট্রিংয়ের পুরো অংশের সাথে মেলে কি না তা পরীক্ষা করে।
  • Matcher.find(): প্যাটার্নটি স্ট্রিংয়ের কোনো অংশের সাথে মেলে কি না তা পরীক্ষা করে।
  • Matcher.group(): একটি মেলে পাওয়া অংশ বা গ্রুপ ফেরত দেয়।

2. Java 8 Functional Programming:

Java 8 এর পরে, Functional Programming ধারণাটি Java তে অধিক জনপ্রিয়তা পেয়েছে। এতে Streams, Lambda Expressions, এবং Method References এর মাধ্যমে কমপ্যাক্ট এবং পারফরম্যান্সে দক্ষ কোড লেখা সম্ভব হয়েছে।

Functional Programming এর কিছু প্রধান বৈশিষ্ট্য:

  • Lambda Expressions: অ্যানোনিমাস ফাংশন ব্যবহারের সুবিধা।
  • Streams: ডেটার উপর বিভিন্ন কার্যক্রম (map, filter, reduce) সহজে করা যায়।
  • Method References: ফাংশন অথবা মেথডকে আরও সোজাসুজি এবং সংক্ষিপ্তভাবে ব্যবহার করা।

Regex এবং Functional Programming এর সংমিশ্রণ:

Java 8 এর Streams এবং Lambda Expressions এর মাধ্যমে আপনি Regex ব্যবহার করে অনেক কার্যক্রম খুব সহজে এবং কার্যকরভাবে করতে পারেন। যেমন, একটি স্ট্রিংয়ের মধ্যে নির্দিষ্ট প্যাটার্ন খুঁজে বের করা এবং সেই সমস্ত প্যাটার্নের উপরে কিছু অপারেশন প্রয়োগ করা।

3. Practical Example: Using Regex with Functional Programming (Java 8+)

ধরা যাক, আমাদের একটি লিস্ট আছে স্ট্রিংয়ের, এবং আমরা এই স্ট্রিংগুলো থেকে শুধুমাত্র এমন স্ট্রিংগুলো বের করতে চাই যা একটি নির্দিষ্ট Regex প্যাটার্নের সাথে মেলে। আমরা Streams এবং Lambda Expressions ব্যবহার করে এটা করব।

Example: Find all email addresses from a list of strings using Regex and Streams

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 যদি ইমেইল ঠিকানার ফরম্যাটে হয় তবে তা মেলে।
  • Streams API: .filter() মেথডের মাধ্যমে আমরা স্ট্রিংগুলির মধ্যে ইমেইল ঠিকানাগুলি ফিল্টার করেছি এবং .collect() এর মাধ্যমে সেগুলিকে একটি লিস্টে সন্নিবেশিত করেছি।

4. Filtering and Transformation Using Regex with Streams

এখানে আমরা Regex এবং Functional Programming এর আরও একটি ব্যবহার দেখাবো যেখানে আমরা একটি স্ট্রিংয়ের মধ্যে প্যাটার্ন অনুসারে কিছু অংশ ফিল্টার করব এবং পরিবর্তন (transformation) করব।

Example: Extracting and transforming log messages with a specific pattern (e.g., extracting dates from logs)

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)): এই লাইনটি লগের প্রথম ১০টি ক্যারেক্টার (যেটি তারিখ অংশ) বের করার জন্য ব্যবহার করা হয়েছে।
  • Streams API এর মাধ্যমে আমরা পুরো প্রক্রিয়াটি কমপ্যাক্ট ও কার্যকরভাবে সম্পন্ন করেছি।

5. Combining Multiple Regex Operations with Functional Programming

ধরা যাক, আমাদের লগ ফাইলের মধ্যে থেকে 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 আলাদা করেছি।
  • Streams API এবং Lambda Expressions এর মাধ্যমে পুরো প্রক্রিয়াটি খুব কমপ্যাক্ট এবং সহজে করা হয়েছে।

  • Java Regex এবং Functional Programming এর সংমিশ্রণ Java 8+ এর স্ট্রিমস, ল্যাম্বডা এক্সপ্রেশনস এবং মেথড রেফারেন্সের মাধ্যমে কোডিংকে আরও শক্তিশালী এবং সংক্ষিপ্ত করে তোলে।
  • Regex এর সাহায্যে প্যাটার্ন ম্যাচিং, টেক্সট পার্সিং এবং টেক্সট ম্যানিপুলেশন অনেক সহজ হয়, এবং Streams এবং Lambda Expressions দিয়ে আপনি এই অপারেশনগুলোকে আরও কার্যকর এবং পারফরম্যান্সে দক্ষভাবে করতে পারেন।
  • Java 8 এর পরে, আপনি Regex এবং Functional Programming এর একত্রিত ব্যবহার দিয়ে আরও উন্নত এবং সুন্দর কোড লিখতে পারবেন।
Content added By

Lambda Expressions এবং Regex Integration

85
85

Java 8 এ Lambda Expressions এবং Streams API পIntroduced, যা কোড লেখার পদ্ধতিকে আরও কার্যকর এবং সংক্ষিপ্ত করে তোলে। Lambda expressions ব্যবহার করে, আপনি functional programming ধারণা Java তে প্রয়োগ করতে পারেন, এবং Regex এর সাথে একত্রে ব্যবহার করে আপনি আরও সংক্ষিপ্ত এবং কার্যকরী কোড তৈরি করতে পারেন।

এখানে আমরা Lambda Expressions এবং Regex এর Integration কিভাবে করা যায়, তা দেখব।


1. Lambda Expressions Recap:

Lambda expression হল একটি ছোট আকারের ফাংশন যা method implementation ছাড়া প্যারামিটার গ্রহণ করে এবং একটি কার্যকরী মান ফেরত দেয়। এটি Functional Interface এর সাথে কাজ করে।

Syntax:

(parameters) -> expression

উদাহরণ:

(int x, int y) -> x + y

এটি একটি Functional Interface এর মেথড apply(int x, int y) কে বাস্তবায়িত করবে।


2. Regex এবং Lambda Integration

Regex ব্যবহার করে আপনি স্ট্রিং ম্যানিপুলেশন, ফিল্টারিং, এবং প্যাটার্ন ম্যাচিং কাজ করতে পারেন, এবং যখন আপনি Lambda expressions এর সাথে এটি ইন্টিগ্রেট করেন, তখন আপনি আরও দ্রুত এবং সংক্ষিপ্ত কোড লিখতে পারবেন।

Lambda Expressions ব্যবহার করে Regex Matching

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

ব্যাখ্যা:

  • Lambda Expression: s -> s.matches(pattern) এখানে matches() method ব্যবহার করা হয়েছে যেটি Regex প্যাটার্নের সাথে স্ট্রিং ম্যাচিং চেক করে। এটি একটি functional interface হিসেবে কাজ করে এবং স্ট্রিং ফিল্টার করার জন্য ব্যবহার করা হয়েছে।
  • Stream API: strings.stream() ব্যবহার করে স্ট্রিংগুলির একটি স্ট্রিম তৈরি করা হয়েছে এবং তারপর .filter() ব্যবহার করে শুধুমাত্র সেই স্ট্রিংগুলোকে ফিল্টার করা হয়েছে যেগুলোর সাথে regex প্যাটার্ন মেলে।

3. Regex Substitution with Lambda Expressions

একটি সাধারণ ব্যবহার হতে পারে 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#

ব্যাখ্যা:

  • Lambda Expression: s -> s.replaceAll(pattern, "#") এখানে replaceAll() মেথড ব্যবহার করা হয়েছে যা স্ট্রিংয়ের মধ্যে সংখ্যাগুলোকে # দিয়ে প্রতিস্থাপন করেছে। এটি Lambda expression এর মাধ্যমে প্রতিটি স্ট্রিংয়ের উপর প্রয়োগ করা হয়েছে।
  • Stream API: স্ট্রিম ব্যবহার করে একটি তালিকায় প্রতিটি স্ট্রিংয়ের উপর substitution করা হয়েছে এবং নতুন স্ট্রিংয়ের তালিকা তৈরি করা হয়েছে।

4. Using Regex with Complex Lambda Expressions

এখন একটি আরও উন্নত উদাহরণ দেখি যেখানে আমরা stream এবং regex এর সাথে আরও জটিল Lambda expressions ব্যবহার করি।

উদাহরণ: যদি আমরা এমন একটি List of Strings থেকে শুধুমাত্র সেগুলো নির্বাচন করতে চাই যা একটি নির্দিষ্ট প্যাটার্নের মধ্যে থাকে এবং তারপর তাদের uppercase করে দিতে চাই।

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

ব্যাখ্যা:

  • Lambda Expression: s -> s.matches(pattern) এবং s -> s.toUpperCase()—এখানে প্রথমে regex matching এর মাধ্যমে সঠিক স্ট্রিং নির্বাচন করা হয়েছে এবং তারপর uppercase রূপান্তর করা হয়েছে।
  • Stream API: .filter() মেথডটি regex প্যাটার্নের সাথে মিলে এমন স্ট্রিং ফিল্টার করে এবং .map() মেথডটি প্রত্যেকটি স্ট্রিংকে uppercase রূপে রূপান্তর করে।

5. Performance Considerations

Performance Tips for Lambda and Regex:

  1. Avoid Repeated Regex Compilation: প্রতিবার Regex প্যাটার্ন কম্পাইল করার পরিবর্তে, একবার Pattern.compile() ব্যবহার করুন এবং তারপর ব্যবহার করুন। এটি Regex প্যাটার্নের কম্পাইল করার খরচ কমাবে।
  2. Use Efficient Patterns: Regex প্যাটার্নগুলি যতটা সম্ভব কার্যকর এবং সুনির্দিষ্ট হতে হবে। যেমন, যত কম ক্যাপচারিং গ্রুপ ব্যবহার করা যাবে, ততই ভাল।
  3. Parallel Processing: স্ট্রিমের parallel processing ব্যবহার করে আপনি regex ম্যাচিং এর কাজকে অনেক দ্রুত করতে পারেন যদি ডেটার আকার বড় হয়। তবে, এটি ব্যবহার করার আগে পারফরম্যান্স টেস্টিং করা গুরুত্বপূর্ণ।

Lambda Expressions এবং Streams API এর সাথে Regex ইন্টিগ্রেট করে আপনি আরও সংক্ষিপ্ত, পরিষ্কার এবং কার্যকর কোড লিখতে পারেন। এই দুটি শক্তিশালী ফিচারের সংমিশ্রণ আপনার স্ট্রিং ম্যানিপুলেশন এবং প্যাটার্ন ম্যাচিংয়ের কাজকে দ্রুততর এবং আরও উন্নত করে তুলবে। তবে, performance optimization এর জন্য regex কম্পাইলেশন এবং প্যাটার্নের ব্যবহারের উপর নজর রাখা উচিত।

Content added By

Streams API এবং Regex এর সাথে ব্যবহার

78
78

Java 8-এ Streams API এবং Regular Expressions (Regex) ব্যবহারের মাধ্যমে আপনি ডেটা প্রসেসিং এবং প্যাটার্ন ম্যাচিংকে আরও শক্তিশালী, সহজ এবং কার্যকরীভাবে একত্রিত করতে পারেন। Streams API এর মাধ্যমে আপনি ডেটাকে ফিল্টার, ম্যানিপুলেট এবং ট্রান্সফর্ম করতে পারেন, এবং 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);
    }
}

ব্যাখ্যা:

  1. Streams API:
    • data.stream(): data লিস্ট থেকে একটি স্ট্রিম তৈরি করা হয়েছে।
    • .filter(): প্রতিটি স্ট্রিং ফিল্টার করা হচ্ছে একটি শর্তের ভিত্তিতে।
      • এখানে আমরা Regex প্যাটার্ন ব্যবহার করছি ইমেইল বা ফোন নম্বর খুঁজে বের করার জন্য।
    • .collect(Collectors.toList()): ফিল্টার হওয়া স্ট্রিংগুলিকে একটি নতুন লিস্টে সংগ্রহ করা হচ্ছে।
  2. Regex Matching:
    • 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

Streams API এবং Regex এর সুবিধা:

  • Streams API এবং Regex একসাথে ব্যবহার করে আপনি ফিল্টারিং, ট্রান্সফর্মেশন এবং ম্যাচিং অপারেশনগুলোকে কার্যকরভাবে একত্রিত করতে পারেন।
  • Declarative Syntax: Streams API ব্যবহারের মাধ্যমে কোডটি আরও পরিষ্কার এবং ছোট হয়, যা সহজেই বুঝতে এবং রক্ষণাবেক্ষণ করতে সাহায্য করে।
  • Parallelism: Streams API ব্যবহার করলে আপনি অনেক বড় ডেটাসেটের জন্য সহজে parallel processing করতে পারেন।
  • Streams API এবং Regex এর সংমিশ্রণ খুবই শক্তিশালী টুল, যা ডেটা ফিল্টারিং, ভ্যালিডেশন এবং ট্রান্সফর্মেশনকে সহজ করে তোলে।
  • আপনি যখন বড় ডেটাসেটের মধ্যে নির্দিষ্ট প্যাটার্ন খুঁজে বের করতে চান, তখন Streams API এবং Regex একসাথে ব্যবহার করলে আপনার কাজ অনেক সহজ হয়ে যায়।
  • এই পদ্ধতি জাভাতে functional programming ধারণা এবং declarative syntax ব্যবহার করার একটি চমৎকার উদাহরণ।
Content added By

Functional Interfaces এর মাধ্যমে Regex এর ব্যবহার

50
50

Java Reflection Package (java.lang.reflect) এবং Functional Interfaces (যেমন Predicate, Function, Consumer, Supplier) এর মাধ্যমে Regex ব্যবহারের ধারণা একটি অত্যন্ত শক্তিশালী কৌশল, যেখানে আপনি Functional Programming এবং Regex Matching কে একত্রিত করেন। এটি কোডের পুনঃব্যবহারযোগ্যতা এবং পরিষ্কারতাকে বাড়াতে সাহায্য করে, কারণ আপনি রেগুলার এক্সপ্রেশন (Regex) এবং ফাংশনাল ইন্টারফেস ব্যবহার করে বিভিন্ন স্ট্রিং ম্যানিপুলেশন বা প্যাটার্ন ম্যাচিং কার্যক্রমকে আরও সহজ এবং কার্যকরীভাবে বাস্তবায়িত করতে পারেন।

Functional Interfaces:

ফাংশনাল ইন্টারফেস এমন ইন্টারফেস যা শুধুমাত্র একটি অ্যাবস্ট্র্যাক্ট মেথড থাকে। Java-তে একটি Functional Interface ব্যবহার করা হয় যেসব ক্ষেত্রে আপনি lambda expressions বা method references ব্যবহার করতে চান। কিছু উদাহরণ হলো:

  • Predicate<T>: একটি বুলিয়ান মান প্রদান করে, যা সাধারণত একটি শর্ত চেক করার জন্য ব্যবহৃত হয়।
  • Function<T, R>: একটি ইনপুট অ্যারগুমেন্ট গ্রহণ করে এবং একটি আউটপুট প্রদান করে।
  • Consumer<T>: ইনপুট নেয় কিন্তু আউটপুট প্রদান করে না।

Regex এবং Functional Interfaces এর মধ্যে সম্পর্ক:

আপনি Functional Interfaces ব্যবহার করে Regex Matching করতে পারেন, যেমন:

  • Predicate দিয়ে আপনি স্ট্রিংয়ে নির্দিষ্ট প্যাটার্ন মিলছে কিনা তা চেক করতে পারেন।
  • Function দিয়ে স্ট্রিংয়ের উপর রেগুলার এক্সপ্রেশন প্রয়োগ করতে এবং ফলাফল রিটার্ন করতে পারেন।

Regex এবং Functional Interfaces এর উদাহরণ:

1. Predicate দিয়ে Regex Matching:

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

2. Function দিয়ে Regex ব্যবহার:

আপনি 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

3. Consumer দিয়ে Regex ব্যবহার:

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
  • Functional Interfaces এবং Regex একত্রে ব্যবহার করে আপনি জটিল স্ট্রিং ম্যানিপুলেশন এবং প্যাটার্ন ম্যাচিং আরও সহজ, পরিষ্কার এবং কার্যকরভাবে করতে পারেন।
  • Predicate ব্যবহার করে আপনি স্ট্রিংয়ের সাথে প্যাটার্ন ম্যাচিং করতে পারেন এবং একটি শর্ত চেক করতে পারেন।
  • Function ব্যবহার করে আপনি স্ট্রিং ইনপুট নিয়ে কিছু রেগুলার এক্সপ্রেশন প্রক্রিয়া করতে পারেন এবং ফলাফল আউটপুট হিসেবে ফিরিয়ে দিতে পারেন।
  • Consumer ব্যবহার করে আপনি স্ট্রিংয়ের উপর কোনো কার্য সম্পাদন করতে পারেন, যেমন প্যাটার্ন খুঁজে বের করা এবং তা প্রিন্ট করা।

ফাংশনাল ইন্টারফেস এবং রেগুলার এক্সপ্রেশন ব্যবহার করে আপনি কোডটিকে আরও কমপ্যাক্ট এবং রক্ষণাবেক্ষণযোগ্য করতে পারবেন।

Content added By

Java 8 এর অন্যান্য Advanced Features এর সাথে Regex Integration

71
71

Java 8 এ অনেক নতুন functional programming ফিচার যুক্ত করা হয়েছে, যেমন lambda expressions, streams, default methods, Optional এবং আরও অনেক কিছু। এসব ফিচারের সাথে regular expressions (Regex) ব্যবহারের মাধ্যমে কার্যকারিতা আরও উন্নত করা যেতে পারে। নিচে কিছু Java 8 এর advanced features এবং Regex এর integration কিভাবে করা যেতে পারে, তা আলোচনা করা হয়েছে।


1. Lambda Expressions এবং Regex Integration

Lambda expressions Java 8 এ একটি গুরুত্বপূর্ণ বৈশিষ্ট্য যা আপনাকে ছোট ফাংশনগুলি লিখতে সাহায্য করে। আপনি lambda expressions ব্যবহার করে Regex matching এবং filtering এর মতো কাজ সহজেই করতে পারেন।

Lambda Expressions ব্যবহার করে Regex Matching:

ধরা যাক, একটি তালিকা আছে যেটিতে বিভিন্ন স্ট্রিং রয়েছে এবং আপনি চাইছেন 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 প্যাটার্ন মেলানোর জন্য ব্যবহৃত হয়।
  • Lambda expression s -> s.matches(pattern) স্ট্রিংগুলো ফিল্টার করার জন্য ব্যবহার করা হয়েছে।

2. Streams API এবং Regex Filtering

Streams API Java 8 এর অন্যতম গুরুত্বপূর্ণ বৈশিষ্ট্য, যা আপনাকে ডেটার উপর কার্যকরীভাবে কাজ করার সুযোগ দেয়। Regex এর সাথে Streams API ব্যবহার করে আপনি বড় ডেটাসেটের উপর কার্যকরীভাবে Regex মেলানোর কাজ করতে পারেন।

Streams API ব্যবহার করে Regex Matching:

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)
  • ফলস্বরূপ, শুধুমাত্র সেই স্ট্রিংগুলো প্রিন্ট করা হবে যেগুলোর প্রথম অক্ষর 'a'।

3. Optional Class এবং Regex Validation

Optional ক্লাসটি Java 8 এর একটি ফিচার যা নাল ভ্যালু প্রতিরোধে সহায়ক। যখন আপনি একটি স্ট্রিংয়ের ওপর Regex validation করতে চান, তখন Optional ব্যবহার করে আপনি সেফভাবে null checks করতে পারেন।

Optional Class ব্যবহার করে Regex Validation:

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 ফেরত দেবে, এবং ইমেইলটি বৈধ বলে চিহ্নিত হবে।

4. Default Methods and Regex Reusability

Java 8 এ default methods ব্যবহার করে আপনি ইন্টারফেসে মেথডের ডিফল্ট বাস্তবায়ন প্রদান করতে পারেন। আপনি Regex সম্পর্কিত কাজগুলো ইন্টারফেসে ডিফাইন করে default methods ব্যবহার করে কোড পুনরায় ব্যবহারযোগ্য করতে পারেন।

Default Method Example:

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!

ব্যাখ্যা:

  • default method matches() ইন্টারফেসে ডিফাইন করা হয়েছে এবং এটি একটি প্যাটার্নের সাথে স্ট্রিং ম্যাচ করে।
  • ক্লাস RegexWithDefaultMethod এ আমরা এই ডিফল্ট মেথডটি ব্যবহার করেছি।

5. Method References and Regex Integration

Java 8 এ Method References ব্যবহার করে আপনি মেথড কলকে আরও সংক্ষিপ্ত এবং পাঠযোগ্য করতে পারেন। Regex এর ক্ষেত্রে, আপনি method references ব্যবহার করে কিছু প্যাটার্ন মেলানোর কাজ আরও সহজভাবে করতে পারেন।

Method Reference Example:

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 উন্নত করতে সাহায্য করে।

  • Streams API এবং Lambda Expressions ব্যবহার করে আপনি Regex-কে আরও দক্ষতার সাথে একত্রিত করতে পারেন।
  • Default Methods এবং Method References Regex-এর কার্যকারিতা উন্নত করার জন্য ব্যবহৃত হতে পারে।
  • Optional ব্যবহার করে নিরাপদভাবে ইনপুট ভ্যালিডেশন করা সম্ভব।
Content added By
টপ রেটেড অ্যাপ

স্যাট অ্যাকাডেমী অ্যাপ

আমাদের অল-ইন-ওয়ান মোবাইল অ্যাপের মাধ্যমে সীমাহীন শেখার সুযোগ উপভোগ করুন।

ভিডিও
লাইভ ক্লাস
এক্সাম
ডাউনলোড করুন
Promotion