2013-05-12 2 views
3

Я пытаюсь найти что-то и для жизни, я не могу понять, почему это не работает, как ожидалось.Почему шаблон не может соответствовать «/ *!»?

Строка: "/*! preserved */"

Выкройка:

Pattern.compile("(/[*][!](?:.+?)[*]/)", Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE) 
- FAIL 

Выкройка:

Pattern.compile("(/[*](?:.+?)[*]/)", Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE) 
- PASS 

Я только хочу, чтобы поймать комментарии, которые имеют ! сразу после открытия комментария строки. Я даже попытался сокращениями спички к только /*!:

Pattern.compile("(/[*][!])", Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE) 
- FAIL 

Pattern.compile("(/[*!]{2})", Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE) 
- FAIL 

Pattern.compile("(/[*][!])", Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE) 
- FAIL 


Java Version "1.6.0_43" 
Java(TM) SE Runtime Environment (build 1.6.0_43-b01) 
Java HotSpot(TM) 64-Bit Server VM (build 20.14-b01, mixed mode) 

EDIT

Это терпит неудачу, который не имеет смысла для меня, так как моя модель не имеет начала или конца с требованием:

Pattern p = Pattern.compile("(/[*]!.+?[*]/)", Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE); 
Matcher m = p.matcher("this is a test /*! preserved */ this is a test /*! preserved1 */"); 
System.out.println("Pattern: " + p); 
System.out.println("Group: " + m.group(1)); 
System.out.println("Found: " + m.find()); 

Даже сведя его просто соответствовать /*! терпит неудачу:

Pattern p = Pattern.compile("(/[*]!)", Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE); 
Matcher m = p.matcher("this is a test /*! preserved */ this is a test /*! preserved1 */"); 
System.out.println("Match: " + m.find()); 
System.out.println("Pattern: " + p); 
System.out.println("Group: " + m.group(1)); 
+1

'*' - специальный символ, убегающий так: '\\ *' – Doorknob

+8

@Doorknob, ставящий '*' в '[]', как он сделал, делает его совпадающим с литералом '*'. – Kevin

ответ

3
Pattern p = Pattern.compile("(/[*]!.+?[*]/)", Pattern.MULTILINE | Pattern.DOTALL 
      | Pattern.CASE_INSENSITIVE); 
    System.out.println(p.matcher("/*! preserved */").matches()); 

выход

true 
+0

Спасибо, мне пришлось немного подкрутить его, и я все еще смущен тем, почему m.find() возвращает false, но я обновил свой код, чтобы использовать m.matches() – Digitalxero

+0

На самом деле ваш шаблон № 1 работает отлично для меня, как для поиска, так и для матчей. Я просто хотел показать, что он работает, а также это выражение можно немного упростить. Я не знаю, почему это не работает для вас. –

+0

Это не соответствует, если вы добавляете текст до или после комментария. – Digitalxero

-2

Один пример, основанный на Струнный API itshelf для проверки пароля.

String password = "Velu1!"; 
    String pattern = "^(?=.*[a-z])(?=.*[A-Z])(?=.*[[email protected]#$%^&*+=_-])(?=\\S+$).{6,100}$"; 
    if (!password.matches(pattern)) { 
     System.out.println("Invalid Password!"); 
    } else { 
     System.out.println("Valid Password!"); 
    } 

В этом случае ваша картина

String pattern = "(/[*]!.+?[*]/)"; 
+0

. Как это касается вопроса? –

+0

@MikeSamuel Это альтернатива для Java-шаблона/сопоставления в API-интерфейсе String, который я недавно узнал. Для тех, кто беспокоится об использовании шаблона/Matcher; они могут просто использовать только String API. –

2

Взятые из Javadoc для matcher.find().

public boolean find() 

Попытки найти следующую подпоследовательность входной последовательности, которая соответствует шаблону. Этот метод запускается в начале области этого соединителя или, если предыдущий вызов метода был успешным, и счётчик с тех пор не был сброшен, у первого символа, не совпадающего с предыдущим совпадением.

Если матч завершается успешно, более подробную информацию можно получить с помощью методов start, end и group.

Возвращает:

true если, и только если, подпоследовательность входной последовательности соответствует модель этого Сличитель в

поиск начинает поиск с конца последнего матча. Не с начала строки. По этой причине m.find() возвращает false.

Вы можете увидеть это поведение в этом примере.

Pattern p = Pattern.compile(".*(/[*]!.+?[*]/).*", Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE); 
Matcher m = p.matcher("this is a test /*! preserved */ this is a test /*! preserved1 */"); 
//System.out.println("Match: " + m.matches()); 
//System.out.println("Pattern: " + p); 
//System.out.println("Group: " + m.group(1)); 
System.out.println("Found: " + m.find()); 

Это возвращает true. Однако, если вы раскомментируете другие строки, m.find() вернет false.

Если вы позвонили m.reset(), прежде чем звонить m.find(), вы сможете узнать, находится ли шаблон в любом месте строки. Однако это сбрасывает состояние совпадения, которое может быть нежелательно.

Edit:

Чтобы найти все матчи только с помощью поиска можно использовать следующий код. (Обратите внимание на недостающую .*)

Pattern p = Pattern.compile("(/[*]!.+?[*]/)", Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE); 
Matcher m = p.matcher("this is a test /*! preserved */ this is a test /*! preserved1 */"); 
while(m.find()) { 
    System.out.println(m.group()); 
} 

Выход

/*! preserved */ 
/*! preserved1 */ 

Поскольку Matcher.matches() должен соответствовать всю строку вам нужно немного более сложное регулярное выражение, чтобы найти все матчи, которые, вероятно, нежелательно.

+0

Дело в том, что шаблон OP потребляет всю строку (обратите внимание на '. *' Сзади), а также '. *' Спереди, поэтому он не может найти все совпадения. Даже если вы используете 'find()', проблема не решена. – nhahtdh

+0

@FDinoff Чтобы сделать это, я думаю, вы также должны указать, что 'matches()' должны соответствовать всей строке, чтобы возвращать 'true'. Также нужно вызвать 'reset()' после вызова 'matches()' также (перед вызовом 'find()'). – acdcjunior

+0

@nhahtdh Я отредактировал сообщение, чтобы показать, как найти все совпадения с помощью 'find()' – FDinoff

Смежные вопросы