поиск слов с помощью [a-zA-Z] из предложения с помощью регулярных выражений - PullRequest
4 голосов
/ 16 января 2012

Я пытаюсь получить все слова в предложении с регулярным выражением, но только слова с [a-zA-Z]. Так что для "я мальчик" я хочу {"я", "я", "а", "мальчик"} но для "I a1m a b * y" я хочу {"I", "a"}, потому что "a1m" и "b * y" включают символы, отличные от [a-zA-Z].

Итак, чтобы получить слова, я пытаюсь проверить

  1. если он находится в начале строки, тогда я проверяю, есть ли пробел после слова
  2. иначе есть пробел до и после слова
  3. если это последнее слово, то проверьте, есть ли пробел перед словом.

Итак, я получил что-то подобное в Java:

Pattern p = Pattern.compile("^[a-zA-Z]+ |^[a-zA-Z]+$| [a-zA-Z]+$| [a-zA-Z]+");
Matcher m = p.matcher("i am good");
while(m.find()) System.out.println(m.group());

Однако я получаю только " i " и " good ". Потому что когда я получаю «я», после «я» есть один пробел. Таким образом, оставленная строка: " am good " Поскольку " am " не находится в начале строки и не имеет пробела перед словом, оно не возвращается.

Ребята, можете ли вы дать какие-либо отзывы по этому поводу? Есть ли способ просто посмотреть на следующий символ и не вернуть пробел?

Ответы [ 3 ]

6 голосов
/ 16 января 2012

Предполагая, что ваш движок регулярных выражений поддерживает утверждения типа lookahead / lookbehind, вы можете использовать что-то вроде следующего:

(^|(?<= )[a-zA-Z]+($|(?= ))

Вот краткое описание того, что делает каждый компонент:

(^|(?<= )): здесь написано "если слово начинается здесь, мы заинтересованы".В частности,
^: соответствует началу строки или
(?<= ): соответствует любой точке, которой предшествует пробел, без фактического использования самого пробела.Это называется положительным взглядом за утверждением.

[a-zA-Z]+: Это должно быть очевидно, но оно соответствует любому ряду последовательных буквенных символов ASCII.

($|(?= )): Это говорит "если словоздесь закончено, мы сделали ".В частности,
$: соответствует концу строки, или
(?= ): соответствует любой точке, за которой следует пробел, фактически не занимая само пространство.Это называется положительным косвенным утверждением.


Обратите внимание, что этот конкретный регулярное выражение не считает слово словом, если за ним следует пунктуация.На самом деле это может быть не то, что вы хотите, но вы описали проверку пробелов, так что это то, что делает регулярное выражение.Если вы хотите поддержать слова, сопровождаемые простой пунктуацией, вы можете изменить этот последний атом на

($|(?=[ .,!?]))

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

2 голосов
/ 16 января 2012

Не могли бы вы использовать вместо этого более простой шаблон, такой как \b[A-Za-z]+\b? (Метасимвол \ b отделяет символы слова (например, буквы) от символов, не являющихся словами (например, пробелы и знаки пунктуации.))

код

Pattern p = Pattern.compile("\\b[A-Za-z]+\\b");
Matcher m = p.matcher("i am good");
while(m.find()) System.out.println(m.group());

Производит {"i", "am", "good"}.

Редактировать Как прокомментировал математический кофе, вышесказанное не работает. Выражение

(?<=^|\s)[A-Za-z]+(?=\W*(?:\s*$|\s))

может работать лучше. Для строки I a1m a b*y boy am is!! or, сопоставление производит "I", "a", "boy", "am", "is", "или".

Если в предыдущем выражении "есть !!" следует игнорировать, вместо этого можно использовать выражение (?<=^|\s)[A-Za-z]+(?=$|\s). В предыдущем примере он не возвращает «есть», но возвращает другие слова (я, а, мальчик, я или).

0 голосов
/ 16 января 2012

Это всего лишь примечание, если вы не хотели использовать что-то, как предложил Кевин Баллард.Вы можете разбить строку на токены, и оттуда вы можете проверить каждый токен, чтобы убедиться, что он содержит только [a-zA-Z].

Чтобы разбить его на токены, сделайте что-то вроде этого:

String message="The text of the message to be scanned.";
StringTokenizer st=new StringTokenizer(message);
while (st.hasMoreTokens())
    {
      checkWord(st.nextToken()); 
       idx++;
    }

И тогда вы бы написали функцию, чтобы проверить, состоит ли этот токен из [a-zA-Z].Так как не будет пробелов, я думаю, вам будет гораздо проще иметь дело с этими токенами, а не со всей строкой.

Удачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...