开发者

Java \ Pattern - how to write a pattern that verifies the lack of a string?

I tried from https://docs.oracle.com/javase/1.5.0/docs/api/java/util/regex/Pattern.html.

I have

Pattern PATTERN = Pattern.compile("agg{0}.*");
Matcher m = PATTERN.matcher("agg_0_4_Jul_2010_13_32_53_759_0.csv");

if (m.matches() == true)  => true.

I want this to return FALSE - since 开发者_如何学JAVAit does contain agg in the string start. In short - how to verify the lack of substring (in a positive way). Thanks.


Note on original pattern

Your original pattern contains the very peculiar agg{0}. It needs to be said that this pattern makes no sense. Due to the way precedence between concatenation and repetition, and the fact that {0} is exactly zero repetition of a pattern, this agg{0} is simply ag.

Thus, you get the following:

Pattern PATTERN = Pattern.compile("agg{0}.*");
Matcher m = PATTERN.matcher("aged gouda yum yum!");
System.out.println(m.matches()); // prints "true"

To illustrate how repetition and concatenation interacts, and how sometimes grouping is required, here are some more examples:

System.out.println(  "hahaha".matches("ha{3}")    ); // prints "false"
System.out.println(  "haaa".matches("ha{3}")      ); // prints "true"
System.out.println(  "hahaha".matches("(ha){3}")  ); // prints "true"

References

  • regular-expressions.info/Repetition and Round Brackets for Grouping

On negating a matching

The original specification isn't very clear, but here are some basic facts:

  • The String class has the following simple non-regex methods:
    • boolean startsWith(String prefix)
    • boolean endsWith(String suffix)
    • boolean contains(CharSequence s)
  • You can negate a boolean using the ! unary boolean complement operator
    • See also: JLS 15.15.6 Logical Complement Operator !

Here are some simple examples:

System.out.println(   "Hello world!".startsWith("Hell")  ); // "true"
System.out.println(   "By nightfall".endsWith("all")     ); // "true"
System.out.println(   "Heaven".contains("joy")           ); // "false"

System.out.println( ! "Hello world!".startsWith("Hell")  ); // "false"
System.out.println( ! "By nightfall".endsWith("all")     ); // "false"
System.out.println( ! "Heaven".contains("joy")           ); // "true"

On negative lookaround

If the combination of Java's logical complement and String's non-regex predicate checks don't work for you, you can use negative lookarounds to negate a match on a pattern.

Generally speaking, if you want to negate what ^pattern$ matches, and for some reason you need this done in the regex itself, you can match on ^(?!pattern$).* instead (perhaps using the single-line mode so the dot matches everything).

Here's an example of matching a*b*, and negating it using negative lookahead:

    String[] tests = {
        "aaabb",
        "abc",
        "bba",
        "aaaa",
        "bbbbbb",
        "what is this?",
    };
    for (String test : tests) {
        System.out.printf("[%s] %s - %s %n",
            test,
            test.matches("a*b*"),
            test.matches("(?!a*b*$).*")
        );          
    }

The above prints:

[aaabb] true - false 
[abc] false - true 
[bba] false - true 
[aaaa] true - false 
[bbbbbb] true - false 
[what is this?] false - true 

References

  • regular-expressions.info/Lookarounds

Related questions

  • Regex to match 1234, 1324, 2341 (all permutations of {1,2,3,4})
  • Checking if every substring of four zeros is followed by at least four ones using regex
  • How does the regular expression (?<=#)[^#]+(?=#) work?
  • Why is negation of a regex needed?

Going back to the question

If you insist on using negative lookarounds, then you can use one of these two patterns depending on what you actually need:

  • ^(?!agg).*$ (see on rubular.com)
    • This matches strings that doesn't start with agg
  • ^(?!.*agg).*$ (see on rubular.com)
    • This matches strings that doesn't contain agg


Simple alternative:

if (!csv.startsWith("agg") {
  // do something
}


Check contains , it's a method of String

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜