Совпадение регулярных выражений Java сопоставьте пробелы и символы, не содержащие пробелов, 2 раза

#java #regex

#java #регулярное выражение

Вопрос:

Это шаблон и строка, которые я использую для сопоставления регулярных выражений Java. Мне нужно '/dev/sda6 72342MB 5013MB ' (т. Е. Пробелы без пробелов, а пробелы без пробелов) в одной группе.

 String pattern = ".*n(\S \s ){2}(.*)";
String str = "Filesystem     1MB-blocks   Used Available Use% Mounted onn"  
              "/dev/sda6         72342MB 5013MB   63655MB   8% /common";
Pattern r = Pattern.compile(pattern,  Pattern.DOTALL);
Matcher m = r.matcher(str);
System.out.println(m.group(1));
  

Но это происходит не так, как ожидалось.
Это соответствие

72342 МБ

вместо

/dev/sda6 72342MB

Кто-нибудь может сказать, где я ошибаюсь?

Комментарии:

1. String pattern = ".*n(\S \s \S ).*"; и не забудьте вызвать if (m.matches()) , прежде чем пытаться вызвать m.group(1)

2. Я бы также спросил, всегда ли строка, с которой вы хотите сопоставить, всегда начинается с /dev (или, по крайней мере, всегда начинается с / ) и всегда ли две другие строки для сопоставления заканчиваются на [Bb] .

3. @markspace мне нужно сопоставить символы, не содержащие пробелов, 2 раза, точно так же, как abc 3 пробел def 3 пробел.

4. @ElliottFrisch Вы уверены? Мне нужно сопоставить три вещи, а не две. "'/dev/sda6 72342MB 5013MB' in a single group"

5. @markspace я получаю /dev/sda6 72342MB то, что, по словам OP, они хотели.

Ответ №1:

В вашем коде есть две проблемы.

  • Вам нужно всегда вызывать matches() или find() перед вызовом .group() методов для объекта сопоставления.
  • Во-вторых, ваше регулярное выражение неправильно сгруппировано.

В настоящее время ваша группа будет выдавать только одно / последнее совпадение, поэтому вместо этого вам нужно перенести все ваше выражение в group. Правильное регулярное выражение, которое вам нужно, это,

 .*n((?:\S \s ){2})(.*)
  

Попробуйте эти Java-коды,

 String pattern = ".*n((?:\S \s ){2})(.*)";
String str = "Filesystem     1MB-blocks   Used Available Use% Mounted onn"  
              "/dev/sda6         72342MB 5013MB   63655MB   8% /common";
Pattern r = Pattern.compile(pattern,  Pattern.DOTALL);
Matcher m = r.matcher(str);
if (m.matches()) {
    System.out.println(m.group(1));
}
  

С принтами,

 /dev/sda6         72342MB 
  

Комментарии:

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

2. ?: используется для создания шаблона без группировки групп, поскольку по умолчанию скобка всегда создает шаблон группировки. Приведенное выше регулярное выражение все равно работало бы даже без ?: в регулярном выражении, но рекомендуется превратить любой шаблон группировки в шаблон без группировки, если они вам не нужны.