tags:

views:

297

answers:

3

I get a string from a array list:

array.get(0).toString()

gives TITLE = "blabla"

I want the string blabla, so I try this :

Pattern p = Pattern.compile("(\".*\")");
Matcher m = p.matcher(array.get(0).toString());
System.out.println("Title : " + m.group(0));

It doesn't work: java.lang.IllegalStateException: No match found

I also try:

Pattern p = Pattern.compile("\".*\"");
Pattern p = Pattern.compile("\".*\"");  
Pattern p = Pattern.compile("\\\".*\\\"");

Nothing matches in my program but ALL patterns work on http://www.fileformat.info/tool/regex.htm

Any Idea? Thanks in advance.

A: 

are you including the double quotes (") in the string?

All your regex' have escaped "s and will only match if the string in the list includes double quote characters.

Cogsy
+3  A: 

You need to call find() or matches() on the Matcher instance first: these actually execute the regular expression and return whether it matched or not. And then only if it matched you can call the methods to get the match groups.

araqnid
In this case, it's find() you want to call.
Alan Moore
That's right. Because it's a dubious guess that if you've compiled a pattern and a made a "Matcher" for a given string that you still want to *find* anything in that string. (If you only want to know if something *matches* the pattern, I don't see why you need a *Matcher* and that the Pattern can't just tell you that itself.) Saving the world through verboseness....
Axeman
If you want shorter code, you can simply write Pattern.matches("regex", input). If you want the pattern compiled just once for several matches, you need to do more, yes. You seem to be complaining that there's no pattern.matches(CharSequence) convenience instance method.After all, you might call matcher.find() multiple times to find multiple matches, which is quite different from doing matcher.matches() or matcher.lookingAt().
araqnid
+2  A: 

A couple of points:

The Javadoc for Matcher#group states:

IllegalStateException - If no match has yet been attempted, or if the previous match operation failed

That is, before using group, you must first use m.matches (to match the entire sequence), or m.find (to match a subsequence).

Secondly, you actually want m.group(1), since m.group(0) is the whole pattern.

Actually, this isn't so important here since the regexp in question starts and ends with the capture parentheses, so that group(0) is the same string as group(1), but it would matter if your regexp looked like: "TITLE = (\".*\")"

Example code:

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

import org.junit.Test;

@SuppressWarnings("serial")
public class MatcherTest {

    @Test(expected = IllegalStateException.class)
    public void testIllegalState() {
        List<String> array = new ArrayList<String>() {{ add("Title: \"blah\""); }};
        Pattern p = Pattern.compile("(\".*\")");
        Matcher m = p.matcher(array.get(0).toString());
        System.out.println("Title : " + m.group(0));
    }

    @Test
    public void testLegal() {
        List<String> array = new ArrayList<String>() {{ add("Title: \"blah\""); }};
        Pattern p = Pattern.compile("(\".*\")");
        Matcher m = p.matcher(array.get(0).toString());
        if (m.find()) {
            System.out.println("Title : " + m.group(1));
        }
    }
}
toolkit
"Your regexp must match the entire string" -- that's the difference between `matches()` and `find()`, so your first two points aren't quite as distinct as you seem to be implying.
araqnid
hopefully clarified
toolkit