Regex: how can Matcher.matches return true, but Matcher.find return false?

Consider the class below:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexBugDemo {
     private static final Pattern numberPattern;
     static {
               // The BigDecimal grammar below was adapted from the BigDecimal(String) constructor.
               // See also p. 46 of http://www.javaregex.com/RegexRecipesV1.pdf for a regex that matches Java floating point literals; uses similar techniques as below.
          String Sign = "[+-]";
          String Sign_opt = "(?:" + Sign + ")" + "?";     // Note: the "(?:" causes this to be a non-capturing group
          String Digits = "\\p{Digit}+";
          String IntegerPart = Digits;
          String FractionPart = Digits;
          String FractionPart_opt = "(?:" + FractionPart + ")" + "?";
          String Significand = "(?:" + IntegerPart + "\\." + FractionPart_opt + ")|(?:" + "\\." + FractionPart + ")|(?:" + IntegerPart + ")";
          String ExponentIndicator = "[eE]";
          String SignedInteger = Sign_opt + Digits;
          String Exponent = ExponentIndicator + SignedInteger;
          String Exponent_opt = "(?:" +Exponent + ")" + "?";
          numberPattern = Pattern.compile(Sign_opt + Significand + Exponent_opt);
//     private static final Pattern numberPattern = Pattern.compile("\\p{Digit}+");
     public static void main(String[] args) throws Exception {
          String s = "0";
//          String s = "01";
          Matcher m1 = numberPattern.matcher(s);
          System.out.println("m1.matches() = " + m1.matches());
          Matcher m2 = numberPattern.matcher(s);
          if (m2.find()) {
               int i0 = m2.start();
               int i1 = m2.end();
               System.out.println("m2 found this substring: \"" + s.substring(i0, i1) + "\"");
          else {
               System.out.println("m2 NOT find");
          System.exit(0);
}Look at the main method: it constructs Matchers from numberPattern for the String "0" (a single zero). It then reports whether or not Matcher.matches works as well as Matcher.find works. When I ran this code on my box just now, I get:
m1.matches() = true
m2 NOT findHow the heck can matches work and find NOT work? matches has to match the entire input sequence, whereas find can back off if need be! I am really pulling my hair out over this one--is it a bug with the JDK regex engine? Did not seem to turn up anything in the bug database...
There are at least 2 things that you can do to get Matcher.find to work.
First, you can change s to more than 1 digit, for example, using the (originaly commented out) line
          String s = "01";yields
m1.matches() = true
m2 found this substring: "01"Second, I found that this simpler regex for numberPattern
     private static final Pattern numberPattern = Pattern.compile("\\p{Digit}+");yields
m1.matches() = true
m2 found this substring: "0"So, the problem seems to be triggered by a short source String and a complicated regex. But I need the complicated regex for my actual application, and cannot see why it is a problem.
Here is a version of main which has a lot more diagnostic printouts:
     public static void main(String[] args) throws Exception {
          String s = "0";
          Matcher m1 = numberPattern.matcher(s);
          System.out.println("m1.regionStart() = " + m1.regionStart());
          System.out.println("m1.regionEnd() = " + m1.regionEnd());
          System.out.println("m1.matches() = " + m1.matches());
          System.out.println("m1.hitEnd() = " + m1.hitEnd());
          m1.reset();
          System.out.println("m1.regionStart() = " + m1.regionStart());
          System.out.println("m1.regionEnd() = " + m1.regionEnd());
          System.out.println("m1.lookingAt() = " + m1.lookingAt());
          System.out.println("m1.hitEnd() = " + m1.hitEnd());
          Matcher m2 = numberPattern.matcher(s);
          System.out.println("m2.regionStart() = " + m2.regionStart());
          System.out.println("m2.regionEnd() = " + m2.regionEnd());
          if (m2.find()) {
               int i0 = m2.start();
               int i1 = m2.end();
               System.out.println("m2 found this substring: \"" + s.substring(i0, i1) + "\"");
          else {
               System.out.println("m2 NOT find");
               System.out.println("m2.hitEnd() = " + m2.hitEnd());
          System.out.println("m2.regionStart() = " + m2.regionStart());
          System.out.println("m2.regionEnd() = " + m2.regionEnd());
          System.out.println("m1 == m2: " + (m1 == m2));
          System.out.println("m1.equals(m2): " + m1.equals(m2));
          System.exit(0);
     }Unfortunately, the output gave me no insights into what is wrong.
I looked at the source code of Matcher. find ends up calling
boolean search(int from)and it executes with NOANCHOR. In contrast, matches ends up calling
boolean match(int from, int anchor)and executes almost the exact same code but with ENDANCHOR. Unfortunately, this too makes sense to me, and gives me no insight into solving my problem.

bbatman wrote:
I -think- that my originally posted regex is correct, albeit possibly a bit verbose, No, there's a (small) mistake. The optional sign is always part of the first OR-ed part (A) and the exponent is always part of the last part (C). Let me explain.
This is your regex:
(?:[+-])?(?:\p{Digit}+\.(?:\p{Digit}+)?)|(?:\.\p{Digit}+)|(?:\p{Digit}+)(?:[eE](?:[+-])?\p{Digit}+)?which can be read as:
(?:[+-])?(?:\p{Digit}+\.(?:\p{Digit}+)?)        # A
|                                               # or
(?:\.\p{Digit}+)                                # B
|                                               # or
(?:\p{Digit}+)(?:[eE](?:[+-])?\p{Digit}+)?      # COnly one of A, B or C is matched of course. So B can never have a exponent or sign (and A cannot have an exponent and C cannot have a sign).
What you probably meant is this:
(?:[+-])?                                   # sign       
    (?:\p{Digit}+\.(?:\p{Digit}+)?)         #   A
    |                                       #   or
    (?:\.\p{Digit}+)                        #   B
    |                                       #   or
    (?:\p{Digit}+)                          #   C
(?:[eE](?:[+-])?\p{Digit}+)?                # exponent
and that this must be a sun regex engine bug, but would love to be educated otherwise. Yes, it looks like a bug to me too.
A simplified version of this behavior (in case you want to file a bug report) would look like this:
When `test` is a single digit, m.find() returns _false_ but matches() returns true.
When `test` is two or more digits, both return true, as expected.
public class Test {
    public static void main(String[] args) {
        String test = "0";
        String regex = "(?:[+-])?(?:\\p{Digit}+\\.(?:\\p{Digit}+)?)|(?:\\.\\p{Digit}+)|(?:\\p{Digit}+)(?:[eE](?:[+-])?\\p{Digit}+)?";
        java.util.regex.Matcher m = java.util.regex.Pattern.compile(regex).matcher(test);
        System.out.println("matches() -> "+test.matches(regex));
        if(m.find()) {
            System.out.println("find()    -> true");
        } else {
            System.out.println("find()    -> false");
}

Similar Messages

  • I synced two of my email accounts via gmail's POP3 thing. But now my iphone's gmail inbox shows a random selection of emails (not most recent ones that are in my inbox). How can I make my iphone inbox match what I see when I log on using a PC?

    I synced two of my email accounts via gmail's POP3 capabilities. But now my iphone's gmail inbox only shows a random selection of emails (i.e. right now it is May 31, 2013 but the emails in my inbox are a couple from Nov 12, a few from Oct 12, and then some way older than that and so on.When I log into my gmail from a computer, I see all my emails in the logical, standard order. How can I make my iphone inbox match what I see when I log on using a PC?

    If you're trying to decide between using POP and IMAP, we encourage you to use IMAP.
    Unlike POP, IMAP offers two-way communication between your web Gmail and your email client. This means when you log in to Gmail using a web browser, actions you perform on email clients and mobile devices (ex: putting mail in a 'work' folder) will instantly and automatically appear in Gmail (ex: it will already have a 'work' label on that email the next time you sign in).
    IMAP also provides a better method to access your mail from multiple devices. If you check your email at work, on your mobile phone, and again at home, IMAP ensures that new mail is accessible from any device at any given time.
    Finally, IMAP offers a more stable experience overall. Whereas POP is prone to losing messages or downloading the same messages multiple times, IMAP avoids this through two-way syncing capabilities between your mail clients and your web Gmail.
    That is from the page that you linked- does highlighted part of message ring a bell?

  • How can I use regular expression to match this rule

    I have a String ,value is "<a>1</a><a>2</a><a>3</a>",and want to match other String like "<a>1</a><a>8</a>",if the one of the first string(like "<a>1</a>") will occur in the second string,then will return true.but I don't know how to write the regular expresstion.
    Thx

    Fine fine. :P
    I was a little bored, so here's some code that uses Strings and a StringBuffer (though you could use a String in place of the StringBuffer). Is this perhaps better? :)
              String testMain = "<a>1</a><ab>2</ab><ab>3</ab>";
              String test = "<ab>1</ab><ab>3</ab>";
              String open = "<ab>";
              String close = "</ab>";
              StringBuffer search = new StringBuffer();
              String checkString = null;
              int lastCheck = 0;
              int start = 0;
              int finish = 0;
              boolean done = false;
              while (!done) {
                   start = test.indexOf(open);
                   finish = test.indexOf(close);
                   if ((start == -1) || (finish == -1)) {
                        System.out.println("No more tags to search for.");
                        done = true;
                   else {
                        checkString = test.substring((start + open.length()), finish);
                        search = new StringBuffer();
                        search.append(open);
                        search.append(checkString);
                        search.append(close);
                        if (testMain.indexOf(search.toString()) != -1) {
                             System.out.println("Found value: " + checkString);
                        test = test.substring(finish + close.length());
    Resulting output:
    Found value: 3
    No more tags to search for.
    -G

  • How can I make address labels, preferably matching Avery sizes, in Pages please?

    How can I make address labels, preferably matching Avery sizes, in Pages please?  Please don't tell me there is no labels facility!!

    If you have your addresses set up in Address Book, the logical place for them, that is also the logical place to print them from.
    Pages will only use one data set per page, although there are ways around this. But then that wasn't your question.
    Peter

  • My Apple ID changed back to an old ID when I installed last update on my iPhone 5s.  How can I change it back to match what is on my MacBook Pro and iPad?

    My Apple ID changed back to an old ID when I installed last update on my iPhone 5s.  How can I change it back to match what is on my MacBook Pro and iPad?

    Hi GlendaGirl,
    Thanks for visiting Apple Support Communities.
    It sounds like you're unexpectedly seeing the incorrect Apple ID on your iPhone 5s. You can use these steps to sign out of iCloud on your iPhone 5s and sign in with the right Apple ID:
    iOS 6 and later: Go to Settings > iCloud.
    If you're still signed in with your previous Apple ID:
    Scroll down and tap Delete Account [Sign Out in iOS 8.] Depending on what iCloud options are turned on, you'll be asked to confirm that you want to delete data from your device. To confirm, tap Delete. (If you're using iOS 7 and have Find My iPhone turned on, you'll be asked to enter the password for your previous Apple ID. Enter the password, then tap Turn Off.) The data will be deleted from your device, but not from iCloud.
    Enter your current Apple ID to sign in. The data from your iCloud account will download again to your device.
    From:
    Apple ID: What to do after you change your Apple ID - Apple Support
    Best Regards,
    Jeremy

  • Hello, my iTunes dates are crashed on my mac, how can I download all my itunes match songs and save on my mac?

    Hello, my iTunes dates are crashed on my mac, how can I download all my itunes match songs and save on my mac?

    Hi mrmoo13!
    You have a couple of options for transferring your music library from one computer to another. First, you can download all of your music that is stored in the cloud on iTunes Match by following the instructions on this page:
    iTunes 11 for Mac: Access all your music anytime, anywhere with iTunes Match
    http://support.apple.com/kb/PH12284
    You can follow steps listed in the section right here:
    Play or download songs from iCloud
    You can play songs directly from iCloud, or you can download songs so you can play them when you’re not connected to the Internet.
    If a song is available in iCloud, it has a Download button next to it.
    To play the song, double-click it.
    To download the song, click the Download button.
    After you download a song to a computer, it remains in the computer’s iTunes library, even if you turn off iTunes Match.
    To only display downloaded songs in your iTunes library, choose View > Hide Music in the Cloud. This also hides any previous iTunes Store purchases you haven’t downloaded.
    For information about downloading and playing songs on an iOS device, see the documentation for the device.
    In order to make it easier to download all of your music, you can highlight all of the songs in your iTunes Match section and then click download, as mentioned in these instructions.
    You can also choose to transfer the music from your old computer to the new one by following the steps in this article, whcih will give you some other options for doing this transfer:
    iTunes: How to move your music to a new computer
    http://support.apple.com/kb/ht4527
    Take care, and thanks for visiting the Apple Support Communities.
    -Braden

  • How can i make simple program to match colors ?(photos taken by camera)

    how can i make simple program to match colors ?(photos taken by camera)

    Hi khaledyr,
    use a "random number" and compare for ">0.5" to get a (1 or 0) signal
    What exactly are you searching for?
    - Hints for choosing hardware?
    - How to output voltage or relais signals?
    - Help on using DAQ(mx)?
    - Help on generating (boolean) waveforms?
    Message Edited by GerdW on 04-16-2010 08:15 AM
    Best regards,
    GerdW
    CLAD, using 2009SP1 + LV2011SP1 + LV2014SP1 on WinXP+Win7+cRIO
    Kudos are welcome

  • Using `n how can i add two empty line (two carriage return), between these two lines in the output file?

    hi friends
    using `n   how can i add two empty line (two carriage return), between these two lines in the output file?
    PS C:\> $env:COMPUTERNAME | add-content c:\file.txt
    PS C:\> $Env:USERDOMAIN  | add-content c:\file.txt
     i tested "$env:computername`n`n`n$env:userdomain" | add-content c:\file.txt   but it results in 
    myPCMyDomain
    but i wanted the contents of the output file be like this:
    MyPC
    #empty line here 
    #empty line here
    MyDomain
     i tested many other forms but didn't work.
    thanks

    I tried it, as well. The line breaks were respected in the PowerShell console, Programmer's Notepad, and Word; they weren't in Notepad.
    You are using a Unicode file.  Locale is what?
    If you just want notepad compatible line breaks then do this:
    del file.txt ; "$env:computername`r`n`r`n`r`n$env:userdomain" | add-content file.txt ;notepad file.txt
    Look in hex to see that `n is ^L or 0xA and is only one character.  CrLf is 0xD 0xA - two characters.
    My programmers editors and VS all understand a single ^L as a line break so does PowerShell.  Only DOS/Notepad and other utilitis don't understand this..
    ¯\_(ツ)_/¯

  • How can I decrease the leading on all hard returns?

    How can I decrease the leading on all hard returns? I have a paragraphs that has 12pt leading, but I want 8pt leading on the returns. Is there a way to change them all at the same time? I know you can increase them by using the space before and after tabs. They only let you go from 0" and up, but not in the negative.

    I figured it out. Instead of having two hard returns I just used one and used the space after. I was using the space after and before option incorrectly. Thank you.

  • I am trying to delete pages I have crated in numbers, but can only see them in print preview. Without print preview I do not see them. How can I delete these pages, but keep others before and after?

    I am trying to delete pages I have crated in numbers, but can only see them in print preview. Without print preview I do not see them. How can I delete these pages, but keep others before and after?

    Hi Crushed,
    Numbers doesn't have pages. It has a canvas that holds objects such as tables and charts.
    Drag the objects from the bottom of the canvas onto the white space above. That will reduce the number of "pages" (sheets of paper) that will print.
    Regards,
    Ian.

  • How can i create multiple accounts but use the same itunes?

    how can i create multiple accounts but use the same itunes?

    Hi iCloud is Making Me Go Crazy,
    You will need to create a new Apple ID for your GameCenter and iCloud services.  You can continue to use the current Apple ID you share with your Mom for access to iTunes Store purchases if you wish. 
    Using your Apple ID for Apple services
    http://support.apple.com/kb/HT4895
    Frequently asked questions about Apple ID
    http://support.apple.com/kb/HT5622
    Cheers,
    - Judy

  • I am at capacity How can I free up space but not delete music

    My Ipad is at 55.4 gb used 24 gb in music alone. 2.7 gb available so can't do anything  Ipad shuts itself down and won't let me open mail, use facebook, safari.How can I free up space but not delete songs in library   

    Unless you are attempting to download a sizable file, 2.7 GB should be more than enough to continue fucntioning. Try a reset: Simultaneously hold down the Home and On buttons until the device shuts down. Ignore the off slider if it appears. Once shut down is complete, if it doesn't restart on it own, turn the device back on using the On button. In some cases it also helps to double click the Home button and close all apps from the tray BEFORE doing the reset.

  • Hey my lock screen button and home button jammed it doesnt work.How can I fix this problem.But first of all I live in Turkey.But my Iphone 4 is bought from apple store victoria gardens CA.Do I have warranty in Turkey ?

    Hey my lock screen button and home button jammed it doesnt work.How can I fix this problem.But first of all I live in Turkey.But my Iphone 4 is bought from apple store victoria gardens CA.Do I have warranty in Turkey ?

    The warranty is only good in the country of purchase.

  • How can I add a line but keep the number I have from tmobile

    How can I add a line but keep the number I have from Tmobile

    Hi, Janice!
    I'm just guessing, but I imagine you'd get your question answered faster in the AE forum.

  • How can i format Iphone 4.But i didnt want deleted pictures,programs,musics.How can i do that?

    How can i format Iphone 4.But i didnt want deleted pictures,programs,musics.How can i do that?

    Restoring to factory setting will certainly erase the pics.
    Why don't you import the pics to your computer as you should be doing anyway?

Maybe you are looking for

  • Class/Package problem with tomcat

    Hi everyone, i am pretty new to tomcat and jsp and I have to setup a webapp using tomcat. Actually I setup the tomcat-server and moved all files in the webapps/ROOT/myapp directory. Unfortunately I get the following error-message when I access the ma

  • Keep getting warning message when starting macbook...

    i have Directv, and, the website wanted me to download its player for viewing on laptop. anyway, i went to applications to delete it, which i thought was successful. now, i keep getting a message everytime i jump on my mac that states the following:

  • InDesign CS2 & MAC OX 10.8.x

    just try to install InDesign CS2 on my MAC PRO running 10.8.3 and after installtion a get an error "installation failed" Some suggestions? Best Eric

  • ABAP Query (Transaction KOB1 and KSB1)

    Hallo Friends, I want to generate a query which will consist of some selected columns of the output list of the transactions KOB1 and KSB1 together. Using F1 and F9 to check the Table Fieldname where the contents of the list where selected, has not b

  • Safari Crashes again

    I did JAVA update and other things people have suggested, but I got a crash again today. This is the report. Can anyone tell me why is this happening? Thx. Process: Safari [114] Path: /Applications/Safari.app/Contents/MacOS/Safari Identifier: com.app