开发者

Java regular expression to match a lexicographical range of strings

开发者 https://www.devze.com 2023-03-15 21:21 出处:网络
I have looked through all kinds of Java REGEX information and 开发者_Go百科have not found the answer I\'m looking for:

I have looked through all kinds of Java REGEX information and 开发者_Go百科have not found the answer I'm looking for:

How do I find all Strings that are between two values (abc and def)?

So if I have the following strings:

abc
acc
ace
amf
def
efg
khp
mlo

I would hope to get the following because these are between abc and def (including):

abc 
acc
ace
amf
def


Using regular expressions (not recommended)

There is no direct way of expressing this. It is in fact almost identical to figuring out if a given number is within a specific range. (That is, providing a regular expression matching digits within the range 123-456.)

You can "encode" it with a fairly complex regular expression though. A process which I've described here:

  • How to generate a regular expression at runtime to match a numeric range

For the specific example of "abc" to "def" you would write it like this:

  • a followed
    • b followed by c-z, or
    • c-z followed by any character, or
  • b-c followed by any two characters, or
  • d followed by
    • a-d followed by any character, or
    • e followed by
      • a-f.

Here it is in code:

String pattern = "a(b[c-z]|[c-z][a-z])|[bc][a-z][a-z]|d([a-d][a-z]|e[a-f])";

for (String s: "abc acc ace amf def efg khp mlo".split(" "))
    System.out.println(s + (s.matches(pattern) ? " matches" : ""));

Output:

abc matches
acc matches
ace matches
amf matches
def matches
efg
khp
mlo



Using String.compareTo (recommended)

You should consider comparing the strings instead:

"abc".compareTo(s) <= 0 && s.compareTo("def") <= 0

Example:

String lower = "abc", upper = "def";

for (String s: "abc acc ace amf def efg khp mlo".split(" ")) {
    boolean match = lower.compareTo(s) <= 0 && s.compareTo(upper) <= 0;
    System.out.println(s + (match ? " matches" : ""));
}

Output:

abc matches
acc matches
ace matches
amf matches
def matches
efg
khp
mlo


Are you looking for something like this? (Interpreting "between" as lexical ordering and not as placement within a parent String)

public static boolean between(
    final String candidate, final String left, final String right) {
      return left.compareTo(candidate) <= 0 && candidate.compareTo(right) <= 0;
}

Test code:

public static void main(final String[] args) throws Exception {
    final String[] words = "abc acc ace amf def efg khp mlo".split("\\W+");
    final String left = "abc";
    final String right = "def";
    for (final String word : words) {
        System.out.println(MessageFormat.format("{0}{1}between {2} and {3}",
        word, (between(word, left, right) ? " is " : " is not "), left, right));
    }
}

Output:

abc is between abc and def
acc is between abc and def
ace is between abc and def
amf is between abc and def
def is between abc and def
efg is not between abc and def
khp is not between abc and def
mlo is not between abc and def

0

精彩评论

暂无评论...
验证码 换一张
取 消