использование функции разделителя сканера для «abc-def»

StackOverflow https://stackoverflow.com/questions/750881

Вопрос

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

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

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

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

Спасибо ;)

Это было полезно?

Решение

Хорошо, я угадываю ваш вопрос здесь:вы имеете в виду, что у вас есть текстовый файл с какой-то "настоящей" прозой, т.е.предложения, которые действительно имеют смысл, разделены знаками препинания и тому подобным и т. д., верно?

Пример:

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

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

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

Другие советы

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

Возможно, это то, что вы ищете:

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

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

Это не очень просто.Можно попробовать следующее: {current-delimeter-chars}{ноль-или-более-дефисов}{ноль-или-более-текущий-делитель-символов-или-дефис}.

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

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

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

Примечание:

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

Примечание:

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top