使用正则表达式从句子中找到[a-zA-Z]的单词

时间:2012-01-16 04:26:03

标签: java regex

我试图用正则表达式获得句子中的所有单词,但只有[a-zA-Z]的单词。 因此,对于“我是男孩”,我想要{“我”,“我”,“一个”,“男孩”} 但是对于“我a1m a b * y”,我想要{“I”,“a”}因为“a1m”和“b * y”包括[a-zA-Z]以外的字符。

所以对我说话,我正试图检查

  1. 如果它在字符串的开头,那么我只检查字后面是否有空格
  2. 否则
  3. 之前和之后都有空格
  4. 如果这是最后一个单词,那么检查单词前面是否有空格。
  5. 所以我在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”之后有一个空格。 所以剩下的字符串是“很好” 由于“ am ”不在字符串的开头,也没有在单词之前有空格,因此不会返回。

    你们可以提供任何反馈意见吗? 有没有办法只是偷看下一个角色而不是返回空间?

3 个答案:

答案 0 :(得分:6)

假设您的正则表达式引擎支持前瞻/后瞻断言,您可以使用以下内容:

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

以下是每个组件的详细说明:

(^|(?<= )):这说“如果一个词从这里开始,我们就会感兴趣”。具体来说,
^:匹配行的开头或
(?<= ):匹配任何以空格开头的点,而不实际占用空间本身。这被称为积极的外观断言。

[a-zA-Z]+:这应该是显而易见的,但它匹配任何连续的ASCII字母字符。

($|(?= )):这说“如果这个词在这里完成,我们就完成了”。具体来说,
$:匹配行的结尾,或者 (?= ):匹配任何后跟空格的点,而不实际占用空间本身。这被称为积极的先行断言。


请注意,如果单词后跟标点符号,则此特定正则表达式不会将单词计为单词。这实际上可能不是你想要的,但你描述了检查空格,这就是正则表达式所做的。如果你想支持简单标点符号后面的单词,你可以修改最后一个原子

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

如果后跟空格,句号,逗号,感叹号或问号,则匹配该单词。如果你愿意,你也可以更精细。

答案 1 :(得分:2)

您可以使用更简单的模式,例如\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”}。

修改 正如math.coffee评论的那样,上面的失败。表达式

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

可能会更好。对于字符串I a1m a b*y boy am is!! or,匹配产生“I”,“a”,“boy”,“am”,“is”,“or”。

如果在上一个表达式中“是!!”应该忽略,可以使用表达式(?<=^|\s)[A-Za-z]+(?=$|\s)。在前面的示例中,它不返回“is”但返回其他单词(I,a,boy,am或)。

答案 2 :(得分:0)

如果您不想使用Kevin Ballard建议的内容,这只是一个注释。您可以将字符串分解为标记,然后从那里检查每个标记以确保它仅包含[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]组成。由于没有空白处理空间,我认为你会发现处理这些令牌而不是完整的字符串要容易得多。

祝你好运。