rightdon
rightdon

Reputation: 33

Java RegEx - special character til end of string

Given rules for Strings are

[Random Nr of Letters]##[Random Nr of Letters]#[Random Nr of Letters]##########

String Length has to be 35

My String e.g. looks like

TEST##TESTING#TEST#################

My problem is that I can't detect wrong formats like

TEST##TESTING#TEST##A##############

My method is:

private static boolean test(String test_line) {
    String test = "[A-Z]{1,}##[A-Z]{1,}#[A-Z]{1,}#{1,}";
    Pattern test_pattern = Pattern.compile(test);
    Matcher matcher = test_pattern.matcher(test_line);
    return matcher.find();
}

Is there an easy method with RegEx (I have to use it) like "end this String with # and don't allow other characters".

Another problem: How can I assure that my test won't allow other characters than A-Z 0-9 and #? Something like:

    String test = "([^A-Z][^0-9][#])";
    Pattern test_pattern = Pattern.compile(test);
    Matcher matcher = test_pattern.matcher(test_line);
    return matcher.find();

(with negotiating)

Thanks for the help :)

Upvotes: 3

Views: 511

Answers (4)

Pshemo
Pshemo

Reputation: 124225

Lets do it step by step:

To ensure that some string has specific length regex can look like

^.{35}$

where

  • ^ represents start of string
  • . represents any character (beside line separators)
  • {35} represents how many times previous element (in out case . - any character) can appear, so here regex require 35 characters
  • $ represents end of string

In your case you want to only accept characters in range A-Z and # so you can replace . (any character) with this character-class [A-Z#] so your regex can look like

^[A-Z#]{35}$

But you also want to ensure order of these characters. In other words you also want to check if entire string matches some other regex

^[A-Z]{1,}##[A-Z]{1,}#[A-Z]{1,}#{1,}$

actually instead of {1,} we could simply use + which will give us

^[A-Z]+##[A-Z]+#[A-Z]+#+$

To combine these two regexes you can use look-ahead mechanism which let us peek at characters after position where it was used and check if characters after it matches some additional regex.

So final regex can look like

^(?=[A-Z#]{35}$)[A-Z]+##[A-Z]+#[A-Z]+#+$
    ----------- ------------------------
regex1 (length)  regex2 (order)

Now to avoid recompiling (Pattern.compile(test)) the same regex each time your method is called it is better to store its compiled version outside of method as class field. So try maybe something like

private static Pattern test_pattern = Pattern
        .compile("^(?=[A-Z#]{35}$)[A-Z]+##[A-Z]+#[A-Z]+#+$");

private static boolean test(String test_line) {
    return test_pattern.matcher(test_line).matches();
}

Test

System.out.println(test("TEST##TESTING#TEST#################"));//true
System.out.println(test("TEST##TESTING#TEST##A##############"));//false

Upvotes: 3

sotirojo
sotirojo

Reputation: 11

For the format specified ensuring the last character is a #:

([A-Z]+[#]+){3}

To test the length of the string:

if(test.length == 35)
    // ...

To test and allow digits as well (only alphanumeric and # sign):

([A-Z0-9]+[#]+){3}

To allow lower case letters as well:

(\w+#+){3}

Upvotes: 0

hex494D49
hex494D49

Reputation: 9235

Try this out

[a-zA-Z]+#{2}[a-zA-Z]+#{1}[a-zA-Z]+#{1,}

Or

^([a-zA-Z]+#{2}[a-zA-Z]+#{1}[a-zA-Z]+#{1,})$

Or

^(?=.{35}$)([A-Z]+#{2}[A-Z]+#{1}[A-Z]+#{1,})$

TEST##TESTING#TEST################# // pass
TEST##TESTING#TEST##A############## // fail

Demo

Upvotes: 1

Avinash Raj
Avinash Raj

Reputation: 174706

The below regex would match the lines which satisfies the above mentioned criteria,

^(?=.{35}$)[A-Z0-9]+##[A-Z0-9]+#[A-Z0-9]+#+$

DEMO

It matches the line which contains exactly 35 characters.

Upvotes: 1

Related Questions