Во-первых, хотя символы со специальным значением в регулярном выражении, такие как ?
и .
в целом, должны быть экранированы, их не нужно экранировать, когда они находятся в классе символов, []
.
Итак, ваш вызов split
эквивалентен:
String[] words = s.split("[\\s\\-.'?,_@!]");
Необходимо экранировать только -
, потому что он означает «to» в классе символов.
По сути, вы хотите это рассматривать ", "
как один разделитель. Чтобы сопоставить один или несколько символов, вы должны использовать квантификатор +
:
String[] words = s.split("[\\s\\-.'?,_@!]+");
Здесь вы говорите, что разделитель как минимум один из этих символов в классе символов.
Вот несколько визуализаций, чтобы увидеть, какие символы совпадают, сравните: