Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 19 of 19

Thread: Matcher object .find() method question

  1. #1
    Java kindergarten chronoz13's Avatar
    Join Date
    Mar 2009
    Location
    Philippines
    Posts
    659
    Thanks
    177
    Thanked 30 Times in 28 Posts

    Default Matcher object .find() method question

    given a matcher object has already a pattern to match and a string value to search for.

    1) is the .find() method similar to looping a character sequence just to find a matching pattern?

    for (int x = 0; x < someString.length(); x++) {

    // do some string processing
    }

    2) does the .find() method starts from beginning? something like index '0'

    3) is there a way to reverse the search from last to beginning? .find() but starts from the length of the string value like..

    for (int x = someString.length(); x >= 0; x--) {

    // do some string processing
    }


    the above question arises from the code problem below:
       import java.util.regex.Pattern;
    import java.util.regex.Matcher;
     
    public class Ch9Exercise_20 {
     
        public static void main(String[] args) {
     
            String word = "I love Java";
            Pattern pattern = Pattern.compile("[aeiou]", Pattern.CASE_INSENSITIVE);
            Matcher matcher = pattern.matcher(word);
     
            StringBuffer built = new StringBuffer(word);
     
            if (matcher.find()) {
     
                System.out.println("as" );
                built.insert(matcher.start(), "egg");
            }
     
    // 2nd Approach: it complies with the problem perfectly
    //
    //        for (int x = word.length() - 1; x >= 0; x--) {
    //            
    //            if (("" + word.charAt(x)).matches(pattern.pattern())) {
    //                
    //                built.insert(x, "egg");
    //            }
    //        }
     
            System.out.println(built);
        }
    }

    Problem: Add a string "egg" in the start of every vowel that you can find, in this case the word "I love java" should be
    "eggI leggovegge Jeggavegga", with the second approach (commented) the problem is easy to deal with, but im trying to practice
    Pattern , Matcher and StringBuilder/StringBuffer classes for a more complex but safer String processing, the problem is, i dont
    have a way to make the matcher object to do the search(.find()) from the last index to the beginning index of the word "I love java"

    i notice that the pattern only matches with the character "I" or 'I' that results in an output "eggI love java" , i dont have any idea if the .find() method searches EACH character in the sequence ...


  2. #2
    Super Moderator Sean4u's Avatar
    Join Date
    Jul 2011
    Location
    Tavistock, UK
    Posts
    637
    Thanks
    5
    Thanked 103 Times in 93 Posts

    Default Re: Matcher object .find() method question

    I'm not sure I understand your code. Are you expecting Matcher.find() to work in an if statement the way that String.charAt(int) works in a for loop?

  3. #3
    Java kindergarten chronoz13's Avatar
    Join Date
    Mar 2009
    Location
    Philippines
    Posts
    659
    Thanks
    177
    Thanked 30 Times in 28 Posts

    Default Re: Matcher object .find() method question

    yes, exactly..

  4. #4
    Super Moderator Sean4u's Avatar
    Join Date
    Jul 2011
    Location
    Tavistock, UK
    Posts
    637
    Thanks
    5
    Thanked 103 Times in 93 Posts

    Default Re: Matcher object .find() method question

    API docs:
    The find method scans the input sequence looking for the next subsequence that matches the pattern
    After it has found the next one, the find method is done and returns true. When there are no more to find, the find method returns false. If you want the next next one, you'll have to invoke it again. There's a handy loop statement that keeps looking while a method returns true. I bet you can guess what it is!

  5. #5
    Java kindergarten chronoz13's Avatar
    Join Date
    Mar 2009
    Location
    Philippines
    Posts
    659
    Thanks
    177
    Thanked 30 Times in 28 Posts

    Default Re: Matcher object .find() method question

    hmm you mean,, i cant still use the find method to compensate with the problem?

  6. #6
    Java kindergarten chronoz13's Avatar
    Join Date
    Mar 2009
    Location
    Philippines
    Posts
    659
    Thanks
    177
    Thanked 30 Times in 28 Posts

    Default Re: Matcher object .find() method question

    oh yes, i have used a while loop to the searching
    while (matcher.find()) {
     
                built.insert(matcher.start(), "egg");
            }

    but the output looks like this... hmmm "eggegeggegeggggI love Java"

  7. #7
    Super Moderator Sean4u's Avatar
    Join Date
    Jul 2011
    Location
    Tavistock, UK
    Posts
    637
    Thanks
    5
    Thanked 103 Times in 93 Posts

    Default Re: Matcher object .find() method question

    So close! Read the API doc for Matcher.start(), then go back up to find() and read the next method name down. Which one of those two should you be using?

  8. #8
    Super Moderator Sean4u's Avatar
    Join Date
    Jul 2011
    Location
    Tavistock, UK
    Posts
    637
    Thanks
    5
    Thanked 103 Times in 93 Posts

    Default Re: Matcher object .find() method question

    Soz, that's not right. I misread your code. You need to think about how you're building your new string. Why are you using insert()? If I understand correctly, you should be finding a letter, adding it to the new string, and if it's a vowel, adding 'egg' - right? No that's not right. What you're trying to do is to find a vowel, copy the non-vowel part of the old string to the new string, adding egg, then adding the vowel - is that right?

    You could tackle this problem in one shot using regular-expression-replace. To do that you'd specify a regular expression which was a single vowel as a 'capturing group' and a replacement string which was egg + a reference to the group, so that whatever you found would be replaced by egg+what-you-found. That would be the Pattern-fu way to do it. Both Matcher and String have replaceAll methods which provide this feature in one shot.
    Last edited by Sean4u; September 7th, 2011 at 08:44 AM. Reason: not paying attention thinking out loud

  9. The Following User Says Thank You to Sean4u For This Useful Post:

    chronoz13 (September 7th, 2011)

  10. #9
    Java kindergarten chronoz13's Avatar
    Join Date
    Mar 2009
    Location
    Philippines
    Posts
    659
    Thanks
    177
    Thanked 30 Times in 28 Posts

    Default Re: Matcher object .find() method question

    egg + a reference to the group
    uhm.. thats why im trying to push myself to the limit, because im trying to avoid creating temporary string objects with + operator, i have already solved the problem with a common approach, but it seems like the Matcher class will give me some hard time to deal with this one, well i really appreciate your effort helping me out,, ill just keep on posting here if i got a more specific problem.. ill try to dig in deeper

  11. #10
    Java kindergarten chronoz13's Avatar
    Join Date
    Mar 2009
    Location
    Philippines
    Posts
    659
    Thanks
    177
    Thanked 30 Times in 28 Posts

    Default Re: Matcher object .find() method question

    finally i found the error, and its on me LOL, i just notice im checking the pattern checking things with a different objects, one with a matcher object and another one with a string object.. but im controlling a StringBuffer object, so theres really no way with this thing, but to concatinate strings and create some temporary string objects LOL brain messing code

  12. #11
    Super Moderator Sean4u's Avatar
    Join Date
    Jul 2011
    Location
    Tavistock, UK
    Posts
    637
    Thanks
    5
    Thanked 103 Times in 93 Posts

    Default Re: Matcher object .find() method question

    Did you experiment with capturing groups in your Pattern? Your program is a one-liner (if you use the convenience method String.replaceAll(String, String)) or a three-liner if you use Pattern and Matcher.

  13. #12
    Java kindergarten chronoz13's Avatar
    Join Date
    Mar 2009
    Location
    Philippines
    Posts
    659
    Thanks
    177
    Thanked 30 Times in 28 Posts

    Default Re: Matcher object .find() method question

    ahh not yet.. i dont have any idea how to use group() methods, ... but ill give it a try..

  14. #13
    Java kindergarten chronoz13's Avatar
    Join Date
    Mar 2009
    Location
    Philippines
    Posts
    659
    Thanks
    177
    Thanked 30 Times in 28 Posts

    Default Re: Matcher object .find() method question

    oh there, now i use the .group() method, which is equivalent to

    .substring(matcherObj.start(), matcherObj.end());
    that returns a String object(sequence) where the matcher matches the pattern, im being hard headed right now.. im being isolated (exaggerated) of the idea of avoiding temporary string objects lol, it still returns a string object. :}

  15. #14
    Super Moderator Sean4u's Avatar
    Join Date
    Jul 2011
    Location
    Tavistock, UK
    Posts
    637
    Thanks
    5
    Thanked 103 Times in 93 Posts

    Default Re: Matcher object .find() method question

    You could use group() and do this the hard way, one match at a time (although I imagine almost any way you do this will be creating lots of intermediate strings, it's just that some of them won't do it explicitly). The point about using capturing groups is that you can refer back to what-I-just-matched in your replacement string, so you can apply it to all matches at once if that fits your need.
    package com.javaprogrammingforums.domyhomework;
     
    import java.util.regex.*;
     
    public class PatternReplaceAll
    {
      public static void main(String[] args)
      {
        final Pattern PAT_HELL = Pattern.compile("([hH])(e)(l)(l)");
        final String GREETING = "Hello, World!\nYou can run this from the shell!";
        final String ADVICE = "****(You can't say $1-$2-$3-$4!)";
        Matcher mat = PAT_HELL.matcher(GREETING);
        System.out.println("-> Replacement with a chance to interfere:");
        StringBuffer safeGreeting = new StringBuffer();
        while (mat.find())
          mat.appendReplacement(safeGreeting, ADVICE);
        mat.appendTail(safeGreeting);
        System.out.println(safeGreeting.toString());
        System.out.println("-> One-shot replacement with a compiled Pattern:");
        System.out.println(mat.replaceAll(ADVICE));
        System.out.println("-> Convenient one-shot replacement without pre-compilation:");
        System.out.println(GREETING.replaceAll(PAT_HELL.pattern(), ADVICE));
      }
    }

    I've left out using group() in this example because it's by far the most complicated way to do the thing that regular expressions with capturing groups and back references are best at.

    YouCantSayHell.jar.zip

  16. The Following User Says Thank You to Sean4u For This Useful Post:

    chronoz13 (September 8th, 2011)

  17. #15
    Java kindergarten chronoz13's Avatar
    Join Date
    Mar 2009
    Location
    Philippines
    Posts
    659
    Thanks
    177
    Thanked 30 Times in 28 Posts

    Default Re: Matcher object .find() method question

    i can only say thanks for the code for now.. its way too complicated for me , ill just post further questions if i had,, thanks again so much

  18. #16
    Java kindergarten chronoz13's Avatar
    Join Date
    Mar 2009
    Location
    Philippines
    Posts
    659
    Thanks
    177
    Thanked 30 Times in 28 Posts

    Default Re: Matcher object .find() method question

    oh there, somehow i got the logic of the program, appendReplacement() and appendTail() with the code above, im just confused with the pattern expression
     ([hH])(e)(l)(l)

    does this mean, a character either 'h' or 'H' as a word, and char 'e','l', 'l' as word?

    and the statement
     $1-$2-$3-$4

  19. #17
    Java kindergarten chronoz13's Avatar
    Join Date
    Mar 2009
    Location
    Philippines
    Posts
    659
    Thanks
    177
    Thanked 30 Times in 28 Posts

    Default Re: Matcher object .find() method question

    LOL i made it hahahahaha with the use of Pattern and Matcher class.. hahaha thanks for the hard code mate . i just need some explnation about those two String pattern/expression things above,, well i solved the problem this way

    the target output should be : "eggI leggovegge jeggavegga"
    public static void main(String[] args) {
     
            String word = "I love java";
     
            String vowels = "aeiou";
            StringBuffer built = new StringBuffer();
     
            Pattern pattern = Pattern.compile("[aeiou]", Pattern.CASE_INSENSITIVE);
            Matcher matcher = pattern.matcher(word);
     
            while (matcher.find()) {
     
                matcher.appendReplacement(built, "egg" + word.charAt(matcher.start()));
            }
     
            System.out.println(built);
    }

  20. #18
    Java kindergarten chronoz13's Avatar
    Join Date
    Mar 2009
    Location
    Philippines
    Posts
    659
    Thanks
    177
    Thanked 30 Times in 28 Posts

    Default Re: Matcher object .find() method question

    another question: should i always include an appendTail() everytime i do an Append Replacement? although it does nothing... explicitly..

  21. #19
    Super Moderator Sean4u's Avatar
    Join Date
    Jul 2011
    Location
    Tavistock, UK
    Posts
    637
    Thanks
    5
    Thanked 103 Times in 93 Posts

    Default Re: Matcher object .find() method question

    I think you should have a .appendTail in there for input strings that *don't* end in a vowel. The find / appendReplacement loop is basically what replaceAll does. You would use find / appendReplacement if you wanted to do something with the replacement which would be hard to do in a regular expression, say such as include the number of replacements so far, or a count of how many vowels of each kind you'd seen so far.
    ([hH])(e)(l)(l)
    You should read - about 2,000 times, that's how long it took me - the API doc for java.util.regex.Pattern. The parentheses mark 'capturing groups'. There are 4 capturing groups, each one capturing one character each. The first one matches any character within the square brackets, so a h or a H. The whole pattern will only match Hell or hell. The '[hH]' capturing group is group number 1 in a match, 'e' is group number 2, 'l' is group number 3 and 'l' again is group number 4. It's the same as "([hH])ell" - because the e,l,l groups are literals, they only match themselves. The only useful group is number 1, because it will save the case of the 'h' at the start of the match.
    $1-$2-$3-$4
    I'm using this as replacement string with replace... methods, so they 'know' to interpret the $number as a reference to a capturing group in the matching pattern. The matching string (either "hell" or "Hell") will be replaced by "$1-e-l-l", because capturing groups 2, 3 and 4 are literals which only match one character. The $1 will match either h or H, so the matching text ("hell" or "Hell") will be replaced by "h-e-l-l" or "H-e-l-l". The case of the first character is captured by group number 1.

    Pattern / regular expressions can be tricky to learn, but they're very powerful. Your program can be done in one line with a Pattern in Java, just as I could replace two strings ("Hell" in Hello and "hell" in shell) in one string in my program with one replaceAll invocation. It's good to learn how to do it with the individual methods that give you parts of strings and current match references in Pattern, but it's hard work compared to the way you would do it when you finally figure out what Pattern and Matcher are doing with regular expressions!

  22. The Following User Says Thank You to Sean4u For This Useful Post:

    chronoz13 (September 8th, 2011)

Similar Threads

  1. calling a method from other object: thred
    By Sudheera in forum What's Wrong With My Code?
    Replies: 2
    Last Post: July 18th, 2011, 06:19 AM
  2. Using Queue, cannot find symbol method enqueue
    By firebluetom in forum What's Wrong With My Code?
    Replies: 2
    Last Post: July 17th, 2011, 02:41 PM
  3. [SOLVED] Question About Using Scanner Object Twice
    By derekeverett in forum File I/O & Other I/O Streams
    Replies: 7
    Last Post: July 16th, 2011, 11:36 AM
  4. How to create a new object of another class within a method
    By davie in forum Object Oriented Programming
    Replies: 1
    Last Post: April 16th, 2010, 06:53 PM
  5. cannot find symbol - method
    By kyuss in forum Object Oriented Programming
    Replies: 2
    Last Post: December 7th, 2009, 01:01 PM