1

I have searched everywhere for this but couldn't get a specific solution, and the documentation also didn't cover this. So I want to extract the start date and end date from this string "1-Mar-2019 to 31-Mar-2019". The problem is I'm not able to extract both the date strings.

I found the closest solution here but couldn't post a comment asking how to extract values individually due to low reputation: https://stackoverflow.com/a/8116229/10735227

I'm using a regex pattern to look for the occurrences and to extract both occurrences to 2 strings first.
Here's what I tried:

Pattern p = Pattern.compile("(\\d{1,2}-[a-zA-Z]{3}-\\d{4})");  
Matcher m = p.matcher(str);
while(m.find())
{
    startdt = m.group(1); 
    enddt = m.group(1);   //I think this is wrong, don't know how to fix it
}
System.out.println("startdt: "+startdt+" enddt: "+enddt);

Output is:

startdt: 31-Mar-2019 enddt: 31-Mar-2019

Additionally I need to use DateFormatter to convert the string to date (adding the trailing 0 before single digit date if required).

PrakashG
  • 1,642
  • 5
  • 20
  • 30

3 Answers3

1

You can catch both dates simply calling the find method twice, if you only have one, this would only capture the first one :

String str = "1-Mar-2019 to 31-Mar-2019";

String startdt = null, enddt = null;

Pattern p = Pattern.compile("(\\d{1,2}-[a-zA-Z]{3}-\\d{4})");  
Matcher m = p.matcher(str);
if(m.find()) {
    startdt = m.group(1); 
    if(m.find()) {
       enddt = m.group(1);
    }
}   
System.out.println("startdt: "+startdt+" enddt: "+enddt);

Note that this could be used with a while(m.find()) and a List<String to be able to extract every date your could find.

AxelH
  • 14,325
  • 2
  • 25
  • 55
  • Best suggestion this far, imho. You might also use a longer regex including two dates and capture tham as group 1 and group 2. – Ole V.V. Jul 02 '19 at 08:49
  • @OleV.V. it was the second part of my answer but [Wiktor Stribiżew's answer](https://stackoverflow.com/a/56848631/4391450) post it first ;) – AxelH Jul 02 '19 at 08:50
1

If your text may be messy, and you really need to use a regex to extract the date range, you may use

String str = "Text here 1-Mar-2019 to 31-Mar-2019 and tex there";
String startdt = "";
String enddt = "";

String date_rx = "\\d{1,2}-[a-zA-Z]{3}-\\d{4}";
Pattern p = Pattern.compile("(" + date_rx + ")\\s*to\\s*(" + date_rx + ")");  
Matcher m = p.matcher(str);
if(m.find())
{
    startdt = m.group(1); 
    enddt = m.group(2); 
}
System.out.println("startdt: "+startdt+" enddt: "+enddt);
// => startdt: 1-Mar-2019 enddt: 31-Mar-2019

See the Java demo

Also, consider this enhancement: match the date as whole word to avoid partial matches in longer strings:

Pattern.compile("\\b(" + date_rx + ")\\s*to\\s*(" + date_rx + ")\\b")

If the range can be expressed with - or to you may replace to with (?:to|-), or even (?:to|\\p{Pd}) where \p{Pd} matches any hyphen/dash.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • I went for `Pattern.compile(regexDate + ".*?" + regexDate);` but didn't had the time to post it! This would be the cleanest way to get both date in one regex – AxelH Jul 02 '19 at 08:48
  • @AxelH I am not sure `.*?` is best to detect a datetime range, it is usually expressed with `to` or dashes, so I suggest `date_rx + \s*(?:to|\p{Pd})\s* + date_rx`. – Wiktor Stribiżew Jul 02 '19 at 08:51
  • Yeah, I used a lazy quantifier simply to keep the example readable. But I like that you didn't include the group in `date_rx`, it is reusable ! – AxelH Jul 02 '19 at 08:57
0

You can simply use String::split

String range = "1-Mar-2019 to 31-Mar-2019";
String dts [] = range.split(" ");
System.out.println(dts[0]);
System.out.println(dts[2]);
Scary Wombat
  • 44,617
  • 6
  • 35
  • 64
  • Thank you, but I still want to know how to extract the occurrences through regex, because the string could possibly change (but still have the dates) – Arun Koundinya Jul 02 '19 at 08:44