2016-01-21 2 views
2

С учетом строки S найдите количество слов в этой строке. Для этой проблемы слово определяется строкой из одной или нескольких английских букв.Java Split regex

Примечание: Пространство или любые специальные символы, такие как! [,?. \ _ '@ +] Будут действовать как разделитель.

Формат ввода: Строка будет содержать только строчные английские буквы, верхние регистровые буквы, пробелы и специальные символы:! [,? ._ '@ +].

Формат вывода: в первой строке напечатайте количество слов в строке. Слова не обязательно должны быть уникальными. Затем напечатайте каждое слово в отдельной строке.

Мой код:

Scanner sc = new Scanner(System.in); 
    String str = sc.nextLine(); 
    String regex = "(|!|[|,|?|.|_|'|@|+|]|\\\\)+"; 
    String[] arr = str.split(regex); 

    System.out.println(arr.length); 

    for(int i = 0; i < arr.length; i++) 
     System.out.println(arr[i]); 

Когда я отправить код, он работает чуть более половины тестовых случаев. Я не знаю, что такое тестовые примеры. Я прошу помощи в законе Мерфи. Каковы ситуации, в которых выполняемое мной регулярное выражение не будет работать?

+4

Почему вы включая обратную косую черту в своем регулярном выражении? Этого не требуется. Кроме того, вы используете '[' и ']', не избегая их. –

+3

Для символов со специальным значением в регулярном выражении вам необходимо избегать их. В качестве побочной заметки вам может быть проще и проще разделить на основе набора символов (например, '[a-z]' - это набор всех строчных букв), а не серия X или Y или Z. – Vulcan

+0

Прошу прощения. Не знал, что мне пришлось скрывать обратную косую черту, чтобы опубликовать ее здесь. – juice

ответ

1

В своем регулярном выражении вы не избежите особых символов. Начнем с []. Поскольку вы не избежите их, часть [|,|?|.|_|'|@|+|] рассматривается как набор символов |,?._'@+. Это означает, что ваше регулярное выражение не разбивается на [ и ].

Например, x..]y+[z разделено на x, ]y и [z.

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

String regex = "(|!|\\[|,|\\?|\\.|_|'|@|\\+|\\])+"; 

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

String regex = "[!\\[,?._'@+\\].]+"; 

В этом случае вам нужно только избежать [ и ].

UPDATE:

Там также проблема с ведущим специальный символ (как в вашем примере ".Hi?there[broski.]@@@@@"). Вам нужно разделить его, но в результате получается пустая строка. Я не думаю, что есть способ, чтобы использовать функцию разделения, не производя его, но вы можете уменьшить его путем удаления первой группы перед тем расщеплению с использованием того же регулярное выражение:

String[] arr = str.replaceFirst(regex, "").split(regex); 
+0

Я ценю ваш ответ. Я сделал тестовый ввод «.Hi? There [broski.] @@@@@» без кавычек. Выход напечатан 4, пустая строка, привет, там, broski (каждая на собственной линии). Я предполагаю, что он распечатал пустую строку из-за «.». перед «Привет». Как я могу это исправить? – juice

+0

Да, правильно. См. Мое обновление. – Szymon