Как найти, если строка Java содержит X или Y и содержит Z - PullRequest
3 голосов
/ 17 сентября 2009

Я почти уверен, что регулярные выражения - это путь, но у меня болит голова, когда я пытаюсь определить конкретное регулярное выражение.

Какое регулярное выражение мне нужно найти, если строка Java (содержит текст «ОШИБКА» или текст «ПРЕДУПРЕЖДЕНИЕ») И (содержит текст «синтаксический анализ»), где все совпадения чувствительны к регистру?

РЕДАКТИРОВАТЬ: Я представил конкретный случай, но моя проблема носит более общий характер. Могут быть и другие предложения, но все они включают в себя сопоставление определенного слова, игнорируя регистр. Может быть 1, 2, 3 или более предложений.

Ответы [ 8 ]

19 голосов
/ 17 сентября 2009

Если вам не нравятся регулярные выражения на 100%, не пытайтесь использовать их для чего-то подобного. Просто сделайте это вместо:

string s = test_string.toLowerCase();
if (s.contains("parsing") && (s.contains("error") || s.contains("warning")) {
    ....

потому что, когда вы вернетесь к своему коду через шесть месяцев, вы сразу поймете его.

Редактировать: Вот регулярное выражение, чтобы сделать это:

(?i)(?=.*parsing)(.*(error|warning).*)

но это довольно неэффективно. Для случаев, когда у вас есть условие ИЛИ, гибридный подход, при котором вы ищете несколько простых регулярных выражений и программно комбинируете результаты с Java, как с точки зрения читабельности, так и эффективности.

6 голосов
/ 17 сентября 2009

Если вы действительно хотите использовать регулярные выражения, вы можете использовать оператор позитивный прогноз :

(?i)(?=.*?(?:ERROR|WARNING))(?=.*?parsing).*

Примеры:

Pattern p = Pattern.compile("(?=.*?(?:ERROR|WARNING))(?=.*?parsing).*", Pattern.CASE_INSENSITIVE); // you can also use (?i) at the beginning
System.out.println(p.matcher("WARNING at line X doing parsing of Y").matches()); // true
System.out.println(p.matcher("An error at line X doing parsing of Y").matches()); // true
System.out.println(p.matcher("ERROR Hello parsing world").matches()); // true       
System.out.println(p.matcher("A problem at line X doing parsing of Y").matches()); // false
0 голосов
/ 19 июля 2012

С несколькими .* составами синтаксический анализатор вызовет тысячи пробных совпадений "откат и повтор".

Никогда не используйте .* в начале или в середине шаблона RegEx.

0 голосов
/ 17 сентября 2009

Если у вас переменное количество слов, которые вы хотите сопоставить, я бы сделал что-то вроде этого:

String mystring = "Text I want to match";
String[] matchings = {"warning", "error", "parse", ....}
int matches = 0;
for (int i = 0; i < matchings.length(); i++) {
  if (mystring.contains(matchings[i]) {
    matches++;
  }
}

if (matches == matchings.length) {
   System.out.println("All Matches found");
} else {
   System.out.println("Some word is not matching :(");
}

Примечание: я не скомпилировал этот код, поэтому может содержать опечатки.

0 голосов
/ 17 сентября 2009

Я думаю, что это регулярное выражение поможет (но должен быть лучший способ сделать это):

(.*(ERROR|WARNING).*parsing)|(.*parsing.*(ERROR|WARNING))
0 голосов
/ 17 сентября 2009

Я обычно использую этот апплет , чтобы экспериментировать с рег. ех. Выражение может выглядеть так:

if (str.matches("(?i)^.*?(WARNING|ERROR).*?parsing.*$")) {
...

Но, как указано в ответах выше, лучше не использовать рег. ех. здесь.

0 голосов
/ 17 сентября 2009

Регулярные выражения здесь не нужны. Попробуйте это:

if((string1.toUpperCase().indexOf("ERROR",0) >= 0 ||  
  string1.toUpperCase().indexOf("WARNING",0) >= 0 ) &&
  string1.toUpperCase().indexOf("PARSING",0) >= 0 )

Это также учитывает критерии без учета регистра

0 голосов
/ 17 сентября 2009

попробовать:

 If((str.indexOf("WARNING") > -1 || str.indexOf("ERROR") > -1) && str.indexOf("parsin") > -1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...