user3007858
user3007858

Reputation: 67

Regex year range

import java.util.ArrayList;
import java.util.List;

public class ValidateDemo {
    public static void main(String[] args) {
        List<String> input = new ArrayList<String>();
        input.add("2005-WW-1");
        input.add("3012-W-223");
        input.add("1952-WX-431");
        input.add("19998-d-4134");
        input.add("1899-c-7465");


        for (String car : input) {
            if (car.matches("^\b(19[3-9][0-9]|200[0-9]|201[0-2])\b-?(KK|kk|ww|WW|c|C|ce|CE|cn|CN|cw|CW|d|D|dl|DL|g|G|ke|KE|ky|KY|l|L|ld|LD|lh|LH|lk|LK|lm|LM|ls|LS|mh|MH|mn|MN|mo|MO|oy|OY|so|SO|rn|RN|tn|TN|ts|TS|w|W|wd|WD|wh|WH|wx|WX)-?\\d{1,4}\\d)$")) {
                System.out.println("Car Template " + car);
            }
        }
    }
}

I'm trying to get it to match car reg plates from years 1980-2015 (I know that's not what I have in my pattern) But i keep getting a "Unmatched closing ')' " Error.

So for example "2005-WW-1" should be the only input that will match the pattern.

Upvotes: 0

Views: 601

Answers (4)

Nikos Paraskevopoulos
Nikos Paraskevopoulos

Reputation: 40328

I'd suggest something like Pshemo's answer, implemented as:

import java.util.ArrayList;
import java.util.List;
import java.util.regex.*;

public class ValidateDemo
{
    public static void main(String[] args) {
        List<String> input = new ArrayList<String>();
        input.add("2005-WW-1");
        input.add("3012-W-223");
        input.add("1952-WX-431");
        input.add("19998-d-4134");
        input.add("1899-c-7465");

        String re = "^(\\d+)-?(KK|WW|C|CE|CN|CW|D|DL|G|KE|KY|L|LD|LH|LK|LM|LS|MH|MN|MO|OY|SO|RN|TN|TS|W|WD|WH|WX)-?\\d{1,4}$";
        Pattern p = Pattern.compile(re, Pattern.CASE_INSENSITIVE);

        for (String car : input) {
            Matcher m = p.matcher(car);
            System.out.print(car + " - " + m.matches() + " - ");
            System.out.print(m.group(1));
            int year = Integer.parseInt(m.group(1));
            if( year >= 1980 && year <= 2015 ) System.out.println(" <-- CORRECT");
            else System.out.println();
        }
    }
}

NOTES:

  1. Using case insensitive matching to reduce the size of the RegExp!
  2. Using capturing group to get the year and check it in Java, not monstrous RegExps!
  3. I took out the word boundaries; if this is incorrect depending on your business rules, it can easilly be put back in

Upvotes: 0

Keppil
Keppil

Reputation: 46239

  1. You have an extra closing paranthesis at the end
  2. \b should be \\b
  3. Remove the \\d at the end (or change the one before it to {2,5} if you only want to match 2 to 5)

So, this works:

if (car.matches("^\\b(19[3-9][0-9]|200[0-9]|201[0-2])\\b-?(KK|kk|ww|WW|c|C|ce|CE|cn|CN|cw|CW|d|D|dl|DL|g|G|ke|KE|ky|KY|l|L|ld|LD|lh|LH|lk|LK|lm|LM|ls|LS|mh|MH|mn|MN|mo|MO|oy|OY|so|SO|rn|RN|tn|TN|ts|TS|w|W|wd|WD|wh|WH|wx|WX)-?\\d{1,4}$")) {

Also note that this matches plates from 1930 onwards, not 1980 as you specify in your text.

Upvotes: 0

Jeroen Vannevel
Jeroen Vannevel

Reputation: 44438

Your regex contains 2 opening brackets (() and 3 closing brackets ()).

The error

Unmatched closing ')'

Is fairly descriptive.

I'm assuming you have to add an opening bracket somewhere near the end here:

-?\\d{1,4}\\d)$

My regex is inadequate, but I believe this is what you want:

-?(\\d{1,4}\\d)$

Why don't you just get the first 4 characters and see if they're in a range?

var year = Integer.Parse(myString.SubString(0, 4)); // Error checking omitted

if(year > 1985 && year < 2005) { }

Upvotes: 0

Pshemo
Pshemo

Reputation: 124285

  • remove last closing parenthesis from the end of your regex - it should look like -?\\d{1,4}\\d$" or simpler \\d{2,5}$.
  • change \b (backspace symbol) to \\b if you want it to represent word boundary
  • also, do not check integers range with regex because it is not the proper tool for this. Maintaining such regex would be nightmare. Instead convert part you are interested in to integer (you can use Integer.parseInt(String)) and use proper combination of comparisons operators (<, >, <=, >=).

Upvotes: 1

Related Questions