0

I've got a problem using a regex to match the date in a string. Actually I've got a lot of "date formats" to match but the first one doesn't work and I don't get why it wouldn't work...

The format is like "September 12, 2013" or "May 6, 2014" or "June 02, 2014"...

In my string text, there is the following date : "July 4, 2014".

Here's my code :

Pattern p = Pattern.compile("[a-zA-Z]+ [0-3]?[0-9], (1|2)\\d{3}", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(text);
System.out.println(m.group(1));

But it comes to this error :

Exception in thread "main" java.lang.IllegalStateException: No match found

I even tried with smaller regex but it still doesn't match anything.

Thank you in advance for the help !

Malik
  • 207
  • 1
  • 2
  • 14
  • 1
    You didn't call `find` or `matches` method – anubhava Apr 13 '15 at 08:59
  • you need to use find function. – Avinash Raj Apr 13 '15 at 09:00
  • Don't use a regex to check a date: there are too many edge cases (for example leap years and September 1752). Instead, attempt a parse and handle any exceptions. – Bathsheba Apr 13 '15 at 09:05
  • I suspect that you are misunderstanding what `group(x)` means. Could you explain what result you expect from `m.group(1)`? – Pshemo Apr 13 '15 at 09:06
  • @anubhava @Avunash Raj Thank you, it helped me understanding the problem ^^ @Bathsheba Can you explain me in further details ? ^^ @Pshemo I understand now, it prints me the first match circled with `()` ^^ – Malik Apr 13 '15 at 09:34

3 Answers3

1

You need to invoke Matcher#find() or Matcher#matches() before invoking Matcher#group.

Otherwise, the match is not performed, hence you have neither the whole group, nor any single back-references populated.

Both methods mentioned above return boolean, which will help you infer whether or not your desired group will contain any text.

A typical idiom would be:

if (matcher.find()) {
    // get the group(s)
}

Documentation here.

On the other hand, I would recommend you use DateFormats instead of regular expressions for dates - API here.

Mena
  • 47,782
  • 11
  • 87
  • 106
  • Thank you for your answer, I tried to match with Pattern.matches but it returned false. I even tried with the regex "may" (I found this 3 times in my text) but false as well. Actually I want to find the first date in a String, with a list of date formats I've got, and I wanted to use regex for that, can DateFormat help me find the date in my String ? – Malik Apr 13 '15 at 09:15
  • @Malik `System.out.println(Pattern.matches("[a-zA-Z]+ [0-3]?[0-9], (1|2)\\d{3}", "September 12, 2013"));` returns `true`. Check your input text. – Mena Apr 13 '15 at 09:18
  • I think I understood why I got it wrong, the date is **contained** in the String, it's not the String itself, that's why it returned false – Malik Apr 13 '15 at 09:21
  • Thank you, so I tested `if (m.find()) { System.out.println(m.group(1)); }` and it returns `2`, do you know what's the meaning ? – Malik Apr 13 '15 at 09:25
  • @Malik it means your captured group indexed at `1`, that is, `(1|2)` returned `2`, as expected. – Mena Apr 13 '15 at 09:28
  • I answered to myself by searching, I just circled my regex with (), which printed "July 4, 2014" as expected ! Thank you for the help and sorry for such stupid questions... ^^' So how should I improve it, I want to get the first occurence date from different strings, and all those strings have different formats (and different languages), I'd have used several regex but it's quite inconvenient, can `DateFormat` be more convenient ? – Malik Apr 13 '15 at 09:32
  • @Malik `DateFormat` **are** the way to parse dates! – Mena Apr 13 '15 at 09:41
  • I can't find how to **extract** a date in any format, from a String. – Malik Apr 13 '15 at 09:55
0

You need to check if(m.find()) and print m.group(0) because if you print m.group(1) this will print 1 or 2, (1|2) according to your input, as your input has 2014, m.group(1) will print 2. And m.group(0) means the first group of "[a-zA-Z]+ [0-3]?[0-9], (1|2)\\d{3}" and it prints your full text because it takes your full regex as a first group because there is no other group except (1|2).

Try this code.

String text="July 4, 2014";
Pattern p = Pattern.compile("[a-zA-Z]+ [0-3]?[0-9], (1|2)\\d{3}", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(text);
if (m.find( )) {
    System.out.println(m.group(0));
}else{
    System.out.println("No match found");
}

Output

July 4, 2014

Visit here to know basic with example

Md. Nasir Uddin Bhuiyan
  • 1,598
  • 1
  • 14
  • 24
0

You need to condition for m.find() and print m.group(0) in place of (1).

    String text = "July 4, 2014";
    String pattern = "\\b(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|(Nov|Dec)(?:ember)?)\\D [0-9]{1,2}, [0-9]{4}";

    Pattern r = Pattern.compile(pattern);

    Matcher m = r.matcher(text);
    if(m.find()){
    System.out.println("Found value: " + m.group(0));
    }
Kurenai Kunai
  • 1,842
  • 2
  • 12
  • 22