简体   繁体   中英

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 eg 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 AZ 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 :)

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 AZ and # so you can replace . (any character) with this character-class [AZ#] 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

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

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.

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}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM