2009-04-15 2 views
0

В настоящее время я пытаюсь отфильтровать текстовый файл, содержащий слова, разделенные «-». Я хочу посчитать слова.Использование функции разделителя из сканера для «abc-def»

scanner.useDelimiter(("[.,:;()?!\" \t\n\r]+")); 

Проблема, которая возникает просто: слова, которые содержат «-» будет разделиться и подсчитывали за то, что два слова. Так что просто побег с \ - не является решением выбора.

Как изменить выражение разделителя, чтобы слова типа «foo-bar» оставались, но только «-» будет отфильтрован и проигнорирован?

Спасибо;)

+0

Непонятно, можете ли вы поместить некоторые образцы того, что вы хотите, и чего вы не хотите, пожалуйста? – chburd

+0

@chburd: Я думаю, он хочет, чтобы «один два-три-четыре» были тремя словами. –

ответ

1

ОК, я угадываю ваш вопрос здесь: вы имеете в виду, что у вас есть текстовый файл с некоторой «реальной» прозой, то есть предложения, которые на самом деле имеют смысл, разделены пунктуацией и т. П., Правильно?

Пример:

Эта ситуация улучшается - насколько мы можем сказать - тот факт, что наши самые верные союзники, то Vorgons, продолжают проводить свои стихи хлопать конкурсы; у врага мало стимулов вмешиваться в это, даже с помощью устройств Mute-O-Matic.

Итак, что вам нужно, как разделитель является то, что либо любым количество пробелов и/или знаков препинания (которые вы уже покрытыми регулярным выражением вы показали), или дефис, который окружен по крайней мере один пробел с каждой стороны. Регулярный символ для «или» - «|». Существует ярлык для класса символов пробелов (пробелы, табуляции и строки перевода) во многих реализациях регулярных выражений: «\ s».

"[.,:;()?!\"\s]+|\s+-\s+" 
0

Это не очень просто. Одна вещь, которую нужно попробовать, - {current-delimeter-chars} {zero-or-more-hyphens} {zero-or-more-current-delimeter-chars-or-hyphen}.

Это может быть проще просто игнорировать слова, возвращаемые сканером, состоящие исключительно из дефисов

0

Если можно попытаться использовать предопределенные классы ... делает регулярное выражение гораздо легче читать. См. Java.util.regex.Pattern для параметров.

Может быть, это то, что вы ищете:

string.split("\\s+(\\W*\\s)?" 

Читает: Совпадение 1 или более символов, необязательно следуют ноль или более символов без слов и символ пробела.

+0

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

0
Scanner scanner = new Scanner("one two2 - (three) four-five - ,....|"); 
scanner.useDelimiter("(\\B+-\\B+|[.,:;()?!\" \t|])+"); 

while (scanner.hasNext()) { 
    System.out.println(scanner.next("\\w+(-\\w+)*")); 
} 

NB

следующий метод (String) утверждает, что вы получите только слова с момента первоначального useDelimiter() метод промахов "|"

NB

вы использовали регулярное выражение "\ г \ п | \ п" в качестве линии терминатора. JavaDocs для java.util.regex.План показывает другие возможные терминаторы линии, поэтому более полная проверка будет использовать выражение «\ г \ п | [\ г \ п \ u2028 \ u2029 \ u0085]»

+0

\ B - утверждение с нулевой шириной; он соответствует позиции, которая не является границей слова. Он не использует никаких символов, поэтому нет смысла добавлять к нему «+» или любой другой квантификатор. Java просто игнорирует квантификатор, но некоторые другие варианты регулярных выражений рассматривают его как синтаксическую ошибку. –

+0

Кроме того, OP не использует «\ r \ n | \ n». Он вообще не интересуется разделителями строк. Он просто соответствует наиболее распространенным символам пробела наряду с символами пунктуации в классе символов (но он должен использовать «\ s», как это сделал @Svante). –

+0

он использовал \ r \ n в использованииDelimiter(), btw спасибо за первое разъяснение! :) – dfa

0

Это должно быть достаточно просто: [^\\w-]\\W*|-\\W+

  • Но, конечно, если это проза, и вы хотите, чтобы исключить подчеркивает:
    [^\\p{Alnum}-]\\P{Alnum}*|-\\P{Alnum}+
  • или если вы не ожидаете цифр:
    [^\\p{Alpha}-]\\P{Alpha}*|-\\P{Alpha}+

EDIT: Это более простые формы. Имейте в виду, что полное решение, которое будет обрабатывать тире в начале и конце строк, будет следовать этому шаблону. (?:^|[^\\w-])\\W*|-(?:\\W+|$)

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