2015-09-27 2 views
1

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

in_file.useDelimiter("., !?/@#$%^&*(){}[]<>\\\"'"); 

в данном случае - время выполнения

Exception in thread "main" java.util.regex.PatternSyntaxException: 
Unclosed character class near index 35 

Я попытался с помощью шаблона, такого как время

("\s+,|\s+\?|""|\s:|\s;|\{}|\s[|[]|\s!"); 

перспективы -

Exception in thread "main" java.util.regex.PatternSyntaxException: 
Illegal repetition 

Я знаю Tokenizer но мы ограничены использованием сканера.

+1

Ум, '' '' внутри вашей второй строки не выглядит слишком хорошо. –

ответ

1

Существует метасимвол для извлечения слова: \w. Он выбирает все, что считается словом.

Если вас интересует только слово границ, вы можете использовать \b, что должно быть уместно в качестве разделителя.

См http://www.vogella.com/tutorials/JavaRegularExpressions/article.html (Глава 3.2)

+0

\ w соответствует номерам и символам подчеркивания – RealSkeptic

2

Узор в Scanner должен быть регулярным выражением, которое описывает все символы, которые вы не хотите включить в маркере, повторяется один или несколько раз (это последняя часть потому что слово может быть ограничено более чем одним пробелом/пунктуацией и т. д.)

Это означает, что вам нужен шаблон, который описывает что-то, что не является буквой. Регулярные выражения дают вам возможность отрицать класс символов. Так что, если письмо составляет [a-zA-Z], «небуквенный» - это [^a-zA-Z]. Поэтому вы можете использовать [^a-zA-Z]+ для описания «1 или более не-букв».

Есть и другие способы выразить одно и то же. \p{Alpha} - это то же самое, что и у [a-zA-Z]. И вы отрицаете это, используя P: \P{Alpha}+.

Если ваш файл содержит слова, которые не указаны на английском языке, вы можете использовать категорию Юникод: \P{L}+ (что означает: 1 или более символов, которые не являются буквами Юникода).

Демонстрация:

Scanner sc = new Scanner("Hello, 123 שלום 134098ho こんにちは 'naïve,. 漢字  +?+?+مرحبا."); 
sc.useDelimiter("\\P{Alpha}+"); 
while (sc.hasNext()) { 
    System.out.println(sc.next()); 
} 

Выход:

Hello 
ho 
na 
ve 

Это потому, что мы просили только US-ASCII алфавита (\p{Alpha}). Таким образом, это сломало слово naïve, потому что ï не является буквой в диапазоне US-ASCII. Он также игнорировал все эти слова на других языках.Но если мы будем использовать:

Scanner sc = new Scanner("Hello, 123 שלום 134098ho こんにちは 'naïve,. 漢字  +?+?+مرحبا."); 
sc.useDelimiter("\\P{L}+"); 
while (sc.hasNext()) { 
    System.out.println(sc.next()); 
} 

Тогда мы использовали категорию юникода, а на выходе будет:

Hello 
שלום 
ho 
こんにちは 
naïve 
漢字 
مرحبا 

, который дает вам все слова во всех языках. Так что это ваш выбор.

Резюме

Чтобы создать Scanner разделитель, который позволяет получить все строки, которые сделаны из определенной категории символов (в данном случае, буквы):

  • Создать регулярный выражение для категории ваших символов want
  • Отклонить его
  • Добавить +, чтобы обозначить 1 или более категорий с отрицанием.

Это обычный рецепт, и для сложных случаев может потребоваться другой метод.