0

I need to create a regular expression dynamically for a given set of strings, which are a set of dates.

String dates[] = {"25/11/1995", "26/11/1995", "27/11/1995", "28/11/1995","29/11/1995"};

So the regular expression must be generated as 2[5-9]/11/1995

How can I achieve this is Java 6?

Thiru
  • 2,541
  • 4
  • 25
  • 39
  • 1
    What is the goal next to that ? Because this may not me the better solution – azro Jul 04 '18 at 14:00
  • @azro does not look like a duplicate for me. – lexicore Jul 04 '18 at 14:01
  • It is better to use a Date tool here instead of regex – Youcef LAIDANI Jul 04 '18 at 14:01
  • 1
    Regexes usually don't work very well with dates unfortunately, as the number of days in a month depends on the month and the year (e.g. February). Maybe you could actually parse them all with a proper Date library instead? If you're stuck with Java 7 or below, Joda probably is the best candidate. – sp00m Jul 04 '18 at 14:01
  • 1
    What do you actually try to achieve? Which task are you solving? Looks like a [XY Problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) for me. – lexicore Jul 04 '18 at 14:02
  • I need to use the Jar command to copy all files from a specific date range, the files are named in dates. – Abhishek Gangadhar Jul 04 '18 at 14:02
  • maybe this can help you `for (int i = 5; i <= 9; i++) { System.out.println(String.format("2%i/11/1995", i)); }` – Youcef LAIDANI Jul 04 '18 at 14:04
  • also take a look at this http://www.baeldung.com/java-between-dates – Youcef LAIDANI Jul 04 '18 at 14:05
  • @AbhishekGangadhar Please explain how do you use *Jar command to copy*. – lexicore Jul 04 '18 at 14:21
  • in Linux we would specify the command as follows: jar -cvf /logs.jar /logs/*log.D20180704* The problem is if the number of dates are more and it goes beyond the maximum length of the linux command, then the command won't execute – Abhishek Gangadhar Jul 04 '18 at 14:24
  • @azro This is not the same as the one you specified, cause I don't want the regular expression for other dates except the ones that are in the String Array. – Abhishek Gangadhar Jul 04 '18 at 14:29
  • 1
    @AbhishekGangadhar Can't you just add files one by one or N by N? – lexicore Jul 04 '18 at 14:33
  • Ya but the Linux command line has a limit for the length of the command right?, and I need it to be stored in one jar file. – Abhishek Gangadhar Jul 04 '18 at 14:34
  • 1
    @AbhishekGangadhar Yes Linux command line has a limit for the length but you can do it using for loop , won't take much length if you automate somehow. – Omkar Mozar Jul 04 '18 at 14:36
  • @Omkar By looping I would be creating another jar file on each iteration right? – Abhishek Gangadhar Jul 04 '18 at 14:40
  • An expression that wouldn’t be too hard to generate would be `(25/11/1995)|(26/11/1995)|(27/11/1995)|(28/11/1995)|(29/11/1995)`, but it wouldn’t be very much shorter, so might not solve your problem. – Ole V.V. Jul 04 '18 at 14:43
  • 1
    @AbhishekGangadhar no making temp directory before looping and in looping add the each file you want to temp folder then executing the command - jar -cvf /logs.jar /logs/temp/* After this you can remove the temp directory. – Omkar Mozar Jul 04 '18 at 14:43
  • @AbhishekGangadhar generally regular expressions are made when you know the what are the possible combination can be generated from expression. If you want this to be dynamic. there is no other choice than writing a logical code which would do this.(You can only do it as you know all the cases of it) – Omkar Mozar Jul 04 '18 at 14:50
  • @Omkar ya I had thought about the copying into another directory as well, but thought it would be an inefficient, since we have to copy and then jar. But it looks like that's the only solution. – Abhishek Gangadhar Jul 04 '18 at 15:01
  • @AbhishekGangadhar I think that that will make for a very nice solution. Easy for all to understand, that matters. Don’t worry about efficiency. – Ole V.V. Jul 04 '18 at 15:03

1 Answers1

0

Would something like this get you going?

import java.util.ArrayList;
import java.util.Arrays;

public class MyClass {
    public static void main(String args[]) {
        // Assume all data is dates
        String dates[] = {"25/11/1995", "26/11/1995", "27/11/1995", "28/11/1995","29/11/1995"};

        // Determine the delimeter
        String delimeter = String.valueOf(dates[0].replaceAll("\\d", "").charAt(0));

        // Separate out the days, months, and years distictively
        ArrayList<String> days = new ArrayList<String>();
        ArrayList<String> months = new ArrayList<String>();
        ArrayList<String> years = new ArrayList<String>();
        for (String date : dates) {
            String[] pieces = date.split(delimeter);
            if (!days.contains(pieces[0])) {
                days.add(pieces[0]);
            }

            if (!months.contains(pieces[1])) {
                months.add(pieces[1]);
            }

            if (!years.contains(pieces[2])) {
                years.add(pieces[2]);
            }
        }

        // Generate regex
        System.out.print((days.size() > 1) ? "(" + String.join("|", days) + ")" : days.get(0));  
        System.out.print(delimeter.contentEquals("/") ? "\\" + delimeter : delimeter); 
        System.out.print((months.size() > 1) ? "(" + String.join("|", months) + ")" : months.get(0));
        System.out.print(delimeter.contentEquals("/") ? "\\" + delimeter : delimeter);
        System.out.print((years.size() > 1) ? "(" + String.join("|", years) + ")" : years.get(0));
    }
}

Result:

(25|26|27|28|29)\/11\/1995

I know it's not giving the exact regex you posted in your question, but it is a valid regular expression.

I tested it at Regex101

To get exactly what you're wanting, just make the generating of the regex smarter to recognize sequences.

Shar1er80
  • 9,001
  • 2
  • 20
  • 29
  • Well thought out. If the list was `"31/12/1995", "01/01/1996"`, I get `(31|01)\/(12|01)\/(1995|1996)`, which will include dates that are far from the intended range, though. – Ole V.V. Jul 04 '18 at 16:20
  • @OleV.V. I'm not sure I understand your comment, the expression would still at least find those particular dates. https://regex101.com/r/d314f3/2 – Shar1er80 Jul 04 '18 at 16:37
  • 1
    Again, to say the least, I think I've given the OP a "good" starting point. I'm sure there are edge cases, depending on what the data will actually be. – Shar1er80 Jul 04 '18 at 16:39
  • It will, Shar1er80. I’m just worried whether the asker risks getting log files into his/her JAR that weren’t supposed to go in there. – Ole V.V. Jul 04 '18 at 16:39