Java \ Pattern - как написать шаблон, который проверяет отсутствие строки? - PullRequest
2 голосов
/ 05 июля 2010

Я пытался из http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html

У меня есть

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.

Я хочу, чтобы это возвращало FALSE - так как оно содержит agg в начале строки.короче говоря - как проверить отсутствие подстроки (в позитивном ключе) Спасибо.

Ответы [ 3 ]

10 голосов
/ 05 июля 2010

Примечание по оригинальному рисунку

Ваш оригинальный шаблон содержит очень своеобразный agg{0}. Надо сказать, что этот шаблон не имеет смысла. Из-за приоритета конкатенации и повторения, а также того факта, что {0} является ровно нулевым повторением шаблона, этот agg{0} просто ag.

Таким образом, вы получаете следующее:

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

Чтобы проиллюстрировать, как повторение и сцепление взаимодействуют и как иногда требуется группировка, вот еще несколько примеров:

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"

Ссылки


Об отрицании соответствия

Исходная спецификация не очень ясна, но вот некоторые основные факты:

Вот несколько простых примеров:

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"

Отрицательный взгляд

Если комбинация логического дополнения Java и проверок предикатов без регулярных выражений String не работает для вас, вы можете использовать отрицательные обходные пути, чтобы отрицать совпадение в шаблоне.

Вообще говоря, если вы хотите отрицать то, что соответствует ^pattern$, и по какой-то причине вам нужно сделать это в самом регулярном выражении, вы можете вместо этого сопоставить ^(?!pattern$).* (возможно, используя однострочный режим, чтобы точка соответствовала все).

Вот пример соответствия a*b* и отрицания его с использованием отрицательного взгляда:

    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*$).*")
        );          
    }

Вышеуказанные отпечатки:

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

Ссылки

Похожие вопросы


Возвращаясь к вопросу

Если вы настаиваете на использовании отрицательных поисков, вы можете использовать один из этих двух шаблонов в зависимости от того, что вам действительно нужно:

  • ^(?!agg).*$ ( см. На rubular.com )
    • Соответствует строкам, которые не начинаются с agg
  • ^(?!.*agg).*$ ( см. На rubular.com )
    • Соответствует строкам, которые не содержат agg
1 голос
/ 05 июля 2010

Простая альтернатива:

if (!csv.startsWith("agg") {
  // do something
}
0 голосов
/ 05 июля 2010

Проверка contains, это метод String

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...