我试图用正则表达式获得句子中的所有单词,但只有[a-zA-Z]的单词。 因此,对于“我是男孩”,我想要{“我”,“我”,“一个”,“男孩”} 但是对于“我a1m a b * y”,我想要{“I”,“a”}因为“a1m”和“b * y”包括[a-zA-Z]以外的字符。
所以对我说话,我正试图检查
所以我在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 ”不在字符串的开头,也没有在单词之前有空格,因此不会返回。
你们可以提供任何反馈意见吗? 有没有办法只是偷看下一个角色而不是返回空间?
答案 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]组成。由于没有空白处理空间,我认为你会发现处理这些令牌而不是完整的字符串要容易得多。
祝你好运。