2015-12-17 2 views
-2

Какой шаблон регулярного выражения мне нужно будет передать методу String.split(), чтобы разделить строку на массив подстрок, используя пробел, а также следующие символы в качестве разделителей. (" ! ", " , " , " ? " , " . " , " \ " , " _ " , " @ " , " ' "), и это также может быть сочетание вышеуказанных символов с пробелами. Я пытался что-то вроде этого:Как разбить строку, используя разделители в java?

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.util.*; 
class StringWordCount { 
    public static void main(String[] args) throws IOException { 

     BufferedReader bufferedReader = new BufferedReader(new IputStreamReader(System.in)); 
     String string = bufferedReader.readLine(); 
     String delimiter = "[,\\s]+|\\[!\\s]+|\\[?\\s]+|\\[.\\s]+|\\[_\\s]+|\\[_\\s]+|\\['\\s]+|\\[@\\s]+|\\!|\\,|\\?|\\.|\\_|\\'|\\@"; 
     String[] words = string.split(delimiter); 
     System.out.println(words.length); 
     for(int i = 0; i<words.length; i++) { 
     System.out.println(words[i]); 
     } 
} 

}

Приведенный выше код генерирует только правильный выход для некоторых testcases, в других случаях, он не будет генерировать правильный one.For например, Рассмотрим ниже строки, где он не смог получить ожидаемый результат.

Он генерирует вывод:

23 
Hello 
thanks 
for 
attempting 
this 
problem 

Hope 
it 
will 
help 
you 
to 
learn 
java 

Good 
luck 
and 
have 
a 
nice 
day 

Вместо этого один:

21 
Hello 
thanks 
for 
attempting 
this 
problem 
Hope 
it 
will 
help 
you 
to 
learn 
java 
Good 
luck 
and 
have 
a 
nice 
day 

Как вы можете видеть на первом выходе, его оставляя пространство на комбинации " ! " и [space] а разделителем для вышеуказанной комбинации является \\[!\\s], правильно?

+4

Возможный дубликат [Как разбить строку на Java] (http://stackoverflow.com/questions/3481828/how-to-split-a-string-in-java) – Tushar

+1

@Tushar и другие: вопрос вы называете это «дубликатом», опубликованным кем-то, кто не знал о 'split()'. Этот вопросник знает о 'split' и испытывает трудности с правильной настройкой разделителя. Это не дубликат. – ajb

+0

StringTokenizer более подходит по данному сценарию. хотя он заменен методом Сканера и разделения. –

ответ

2

В этой строке:

String delimiter = "[,\\s]+|\\[!\\s]+|\\[?\\s]+|\\[.\\s]+|\\[_\\s]+|\\[_\\s]+|\\['\\s]+|\\[@\\s]+|\\!|\\,|\\?|\\.|\\_|\\'|\\@"; 

у вас есть в строковый литерал, что означает, что шаблон имеет два символа \[ в нем \\[. В шаблоне шаблона это приводит к тому, что помощник ищет символ [. Это не то, что вы хотите.

Когда появляется \ символ в строке шаблона:

  1. Если следующий символ является буквой или цифрой, то комбинация имеет какой-то особый смысл (например, вы используете \s в строке означает пробел), , но , но:
  2. Если следующий символ - это что-то другое, кроме буквы или цифры, это означает, что для обозначения следующего символа как самого себя. Любое специальное значение, которое может иметь персонаж, было отменено.

Похоже, вы пытаетесь использовать [!\s]+ (в шаблоне, конечно, вы должны были удвоить обратный слеш в строковый литерал), чтобы соответствовать один или несколько символов в наборе ! и пробелов.Здесь [ и ] имеют особое значение для соответствия любому символу в наборе. Но поставив \ перед тем, как [ отменяет специальное значение [, и заставляет матчи искать [ на входе, которого он не находит.

Для получения дополнительной информации см. this javadoc.

Я не уверен, но я думаю, что избавиться от всех \\ перед каждым [ заставит все работать. Шаблон все еще будет более сложным, чем необходимо (и я не на 100% не понимаю, что это за требования, поэтому мне сложно предложить улучшение).

+0

Спасибо @ajb. Извините за то, что не указали точные требования. как я только начал работать на Java. Я должен был увидеть javadoc перед тем, как попытаться решить эту проблему. Получив доступ к этим «\\» перед каждым «[», он точно работал на всех возможных тестовых площадках. Спасибо снова. :) – Batman25663

0

Просто соответствие вместо расщепления ..

ArrayList<String> lst = new ArrayList<String>(); 
Matcher m = Pattern.compile("\\w+").matcher(s); 
while(m.find()) { 
    lst.add(m.group()); 
    } 
4

Вы можете попробовать это одно:

String str = "Hello, thanks for attempting this problem! Hope it will help you to learn java! Good luck and have a nice day!"; 
//String[] split = str.split("[\\p{Punct}\\s+]"); 
String[] split = str.split("[\\p{Punct}\\p{Blank}]+"); 
System.out.println("Arrays.toString(split) = " + Arrays.toString(split)); 

Результат является:

Arrays.toString(split) = [Hello, thanks, for, attempting, this, problem, Hope, it, will, help, you, to, learn, java, Good, luck, and, have, a, nice, day] 

Eited: отредактирован линия ниже

String[] split = str.split("[\\p{Punct}\\p{Blank}]+"); 
Смежные вопросы