রেগেক্স ম্যাচের অ্যারে তৈরি করুন


160

জাভাতে, আমি সমস্ত রেজেক্স ম্যাচগুলিকে একটি অ্যারেতে ফিরিয়ে দেওয়ার চেষ্টা করছি তবে মনে হচ্ছে আপনি কেবলমাত্র প্যাটার্নটি কিছু মিলছে কিনা (বুলিয়ান) যাচাই করতে পারেন।

প্রদত্ত স্ট্রিংয়ে একটি রেজেক্স অভিব্যক্তির সাথে মিলে সমস্ত স্ট্রিংয়ের একটি অ্যারে তৈরি করতে আমি কীভাবে একটি রেজেক্স ম্যাচটি ব্যবহার করতে পারি?


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

3
একটি সত্য লজ্জা। এই কার্যকারিতাটি বাক্সের বাইরে প্রায় প্রতিটি অন্যান্য ভাষায় উপস্থিত রয়েছে বলে মনে হয় (এতে নিয়মিত প্রকাশের সমর্থন রয়েছে)।
রায় তোয়াল

উত্তর:


278

( জাভা> = 9 ধরে নিতে পারলে নীচের চেয়ে 4 ক্যাসলের উত্তরগুলি আরও ভাল)

আপনাকে ম্যাচার তৈরি করতে হবে এবং পুনরাবৃত্তভাবে মিলগুলি খুঁজে পেতে এটি ব্যবহার করতে হবে।

 import java.util.regex.Matcher;
 import java.util.regex.Pattern;

 ...

 List<String> allMatches = new ArrayList<String>();
 Matcher m = Pattern.compile("your regular expression here")
     .matcher(yourStringHere);
 while (m.find()) {
   allMatches.add(m.group());
 }

এর পরে, allMatchesমিলগুলি অন্তর্ভুক্ত করে এবং আপনার allMatches.toArray(new String[0])যদি সত্যিই দরকার হয় তবে আপনি অ্যারে পেতে ব্যবহার করতে পারেন ।


বর্তমান গ্রুপের স্থিতির স্ন্যাপশট ফেরত দেওয়ার MatchResultকারণে আপনি ম্যাচগুলি লুপ করতে সহায়ক ফাংশনগুলি লিখতেও ব্যবহার করতে পারেন Matcher.toMatchResult()

উদাহরণস্বরূপ আপনি করতে একটি অলস পুনরাবৃত্তি লিখতে পারেন

for (MatchResult match : allMatches(pattern, input)) {
  // Use match, and maybe break without doing the work to find all possible matches.
}

এরকম কিছু করে:

public static Iterable<MatchResult> allMatches(
      final Pattern p, final CharSequence input) {
  return new Iterable<MatchResult>() {
    public Iterator<MatchResult> iterator() {
      return new Iterator<MatchResult>() {
        // Use a matcher internally.
        final Matcher matcher = p.matcher(input);
        // Keep a match around that supports any interleaving of hasNext/next calls.
        MatchResult pending;

        public boolean hasNext() {
          // Lazily fill pending, and avoid calling find() multiple times if the
          // clients call hasNext() repeatedly before sampling via next().
          if (pending == null && matcher.find()) {
            pending = matcher.toMatchResult();
          }
          return pending != null;
        }

        public MatchResult next() {
          // Fill pending if necessary (as when clients call next() without
          // checking hasNext()), throw if not possible.
          if (!hasNext()) { throw new NoSuchElementException(); }
          // Consume pending so next call to hasNext() does a find().
          MatchResult next = pending;
          pending = null;
          return next;
        }

        /** Required to satisfy the interface, but unsupported. */
        public void remove() { throw new UnsupportedOperationException(); }
      };
    }
  };
}

এর সাথে,

for (MatchResult match : allMatches(Pattern.compile("[abc]"), "abracadabra")) {
  System.out.println(match.group() + " at " + match.start());
}

উৎপাদনের

a at 0
b at 1
a at 3
c at 4
a at 5
a at 7
b at 8
a at 10

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

13
@ লাইভ, উভয়ই মাপদণ্ডের জন্য সময় নিন ArrayListএবং LinkedListফলাফলগুলি অবাক করে দিতে পারে।
অ্যান্টনি অ্যাকসিওলি

আপনি যা বলছেন আমি তা শুনতে পেয়েছি এবং উভয় ক্ষেত্রেই আমি এক্সিকিউশন স্পিড এবং মেমরির পদচিহ্ন সম্পর্কে সচেতন; অ্যারেলিস্টের সাথে সমস্যাটি হ'ল ডিফল্ট কনস্ট্রাক্টর 10 এর সক্ষমতা তৈরি করে - যদি আপনি সেই সংখ্যার সাথে কলগুলি যোগ করে যান তবে ( ) আপনাকে মেমরি বরাদ্দ এবং অ্যারে অনুলিপি সহ্য করতে হবে - এবং এটি কয়েকবার ঘটতে পারে। মঞ্জুর, আপনি যদি কেবল কয়েকটি ম্যাচ প্রত্যাশা করেন তবে আপনার পদ্ধতিটি আরও কার্যকর; তবে যদি আপনি দেখতে পান যে অ্যারে "রাইজাইজিং" একাধিকবার ঘটে থাকে তবে আমি একটি লিংকডলিস্টের পরামর্শ দেব, এরপরেও যদি আপনি কোনও কম বিলম্বিত অ্যাপ্লিকেশনটি ব্যবহার করছেন।
লিভ

12
@Liv, আপনার প্যাটার্ন মোটামুটি আন্দাজের আকার সঙ্গে ম্যাচ উত্পাদন করতে, এবং (এর লেন্থ এর সমষ্টি উপর ভিত্তি করে প্যাটার্ন জনবিরল বা ঘন সাথে মেলে কিনা তার উপর নির্ভর করে থাকে তাহলে allMatchesবনাম yourStringHere.length()), আপনি সম্ভবত একটি ভাল আকার precompute করতে allMatches। আমার অভিজ্ঞতায় LinkedListমেমরির মূল্য এবং পুনরাবৃত্তির দক্ষতা অনুসারে মূল্য সাধারণত এটি উপযুক্ত LinkedListনয় তবে এটি আমার ডিফল্ট ভঙ্গি নয়। তবে হট স্পটকে অনুকূলকরণ করার সময়, আপনি কোনও উন্নতি পেয়েছেন তা দেখার জন্য তালিকাটি বাস্তবায়নের পক্ষে অদলবদল হওয়া অবশ্যই মূল্যবান।
মাইক স্যামুয়েল

1
জাভা 9, আপনি এখন ব্যবহার করতে পারেন Matcher#resultsপেতে একটি Streamযা আপনাকে একটি অ্যারের জেনারেট করতে ব্যবহার করতে পারেন (দেখুন আমার উত্তর )।
ক্যাসেল

56

জাভা 9, আপনি এখন ব্যবহার করতে পারেন Matcher#results()একটি পেতে Stream<MatchResult>যা আপনি মিলের একটি তালিকা / অ্যারের পেতে ব্যবহার করতে পারেন।

import java.util.regex.Pattern;
import java.util.regex.MatchResult;
String[] matches = Pattern.compile("your regex here")
                          .matcher("string to search from here")
                          .results()
                          .map(MatchResult::group)
                          .toArray(String[]::new);
                    // or .collect(Collectors.toList())

1
তাদের কোনও ফলাফল () পদ্ধতি নয়, অনুগ্রহ করে প্রথমে এটি চালান
ব্রাভো

14
ব্র্যাভো আপনি কি জাভা 9 ব্যবহার করছেন? এটি বিদ্যমান আছে। আমি ডকুমেন্টেশন লিঙ্ক।
ক্যাসেল


25

জাভা রেজেক্সকে খুব জটিল করে তোলে এবং এটি পার্ল-স্টাইল অনুসরণ করে না। আপনি জাভা কোডের একক লাইনে কীভাবে এটি সম্পাদন করতে পারেন তা দেখতে মেন্টারিজেক্সে একবার দেখুন :

String[] matches = match("aa11bb22", "/(\\d+)/g" ); // => ["11", "22"]

6
চমৎকার. ডাবল স্ল্যাশ এখনও কুৎসিত দেখায় তবে আমি অনুমান করি যে এ থেকে কোনও স্কেপ নেই।
জনপ্রস্টাইন

mentaregex-0.9.5.jar, 6Kb যে আমার দিনটি বাঁচিয়েছিল, ওব্রিগাদো সার্জিও!
CONvid19

2
মনোযোগ! সবচেয়ে ভালো সমাধান. এটা ব্যবহার করো!
ভ্লাদ হলুবিভ

13
মেন্টারেজেক্স সাইটটি কি নীচে রয়েছে? আমি যখন mentaregex.soliverajr.com পরিদর্শন করি তখন এটি কেবল "হাই" বলে
ব্যবহারকারী 64141

1
@ ব্যবহারকারী 64৪১৪১ দেখে মনে হচ্ছে
অমিত সোনার

11

এখানে একটি সাধারণ উদাহরণ:

Pattern pattern = Pattern.compile(regexPattern);
List<String> list = new ArrayList<String>();
Matcher m = pattern.matcher(input);
while (m.find()) {
    list.add(m.group());
}

(যদি আপনার আরও ক্যাপচারিং গ্রুপ থাকে তবে আপনি তাদের সূচি দ্বারা গ্রুপ পদ্ধতির আর্গুমেন্ট হিসাবে উল্লেখ করতে পারেন you আপনার যদি অ্যারে দরকার হয় তবে ব্যবহার করুন list.toArray())


প্যাটার্ন.ম্যাচগুলি (ইনপুট) কাজ করে না। আপনাকে আপনার রেজেক্স প্যাটার্নটি পাস করতে হবে (আবার!) -> ডাব্লুটিএফ জাভা ?! প্যাটার্ন.ম্যাচগুলি (স্ট্রিং রেজেক্স, স্ট্রিং ইনপুট); আপনার অর্থ প্যাটার্ন.ম্যাচার (ইনপুট)?
এল ম্যাক

@ এলম্যাক Pattern.matches()একটি স্থিতিশীল পদ্ধতি, আপনার এটি Patternউদাহরণ হিসাবে কল করা উচিত নয় । Pattern.matches(regex, input)এটি কেবল একটি সংক্ষিপ্তকরণ Pattern.compile(regex).matcher(input).matches()
dimo414

5

অফিসিয়াল রেজেক্স জাভা ট্রেলগুলি থেকে :

        Pattern pattern = 
        Pattern.compile(console.readLine("%nEnter your regex: "));

        Matcher matcher = 
        pattern.matcher(console.readLine("Enter input string to search: "));

        boolean found = false;
        while (matcher.find()) {
            console.format("I found the text \"%s\" starting at " +
               "index %d and ending at index %d.%n",
                matcher.group(), matcher.start(), matcher.end());
            found = true;
        }

ব্যবহারের findএবং তার ফলে সন্নিবেশ groupআপনার অ্যারের / তালিকা / যাই হোক না কেন এ।


0
        Set<String> keyList = new HashSet();
        Pattern regex = Pattern.compile("#\\{(.*?)\\}");
        Matcher matcher = regex.matcher("Content goes here");
        while(matcher.find()) {
            keyList.add(matcher.group(1)); 
        }
        return keyList;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.