在Java中通过标点符号和空格等正则表达式来分割字符串

32
我有一个文本文件,我将它读入Java应用程序中,并逐行计算其中的单词数量。目前,我是通过一个

来将行分割成单词。
String.split([\\p{Punct}\\s+])"

但我知道我错过了文本文件中的一些单词。例如,单词"can't"应该分成两个单词"can"和"t"。

逗号和其他标点符号应完全忽略并视为空格。我一直在尝试理解如何形成更精确的正则表达式来做到这一点,但我是一个新手,所以需要一些帮助。

有什么更好的正则表达式可以实现我描述的目的吗?


我认为你不能轻易地使用正则表达式来解决这个问题。虽然你可以解决“无法”的问题,但很快你会面临其他问题。在这里可以看到一些有趣的答案(并不完全是你问题的重复):http://stackoverflow.com/questions/6848869/how-i-count-the-words-and-expressions-in-a-text - Lukas Eder
5个回答

30
您的正则表达式有一个小错误。请尝试使用以下代码:
String[] Res = Text.split("[\\p{Punct}\\s]+");

[\\p{Punct}\\s]++ 的表单移到字符类的外面。否则,您也会在 + 上拆分,并且不会将连续的拆分字符组合在一起。

所以我得到了这段代码

String Text = "But I know. For example, the word \"can\'t\" should";

String[] Res = Text.split("[\\p{Punct}\\s]+");
System.out.println(Res.length);
for (String s:Res){
    System.out.println(s);
}

这个结果

10
但是

知道
例如
这个单词
不能
应该

这应该符合您的要求。

作为替代方案,您可以使用

String[] Res = Text.split("\\P{L}+");

\\P{L} 的意思是不是一个具有“Letter”属性的 Unicode 代码点


P{L} 给了我与您之前的建议相同的输出。谢谢。 - Snorkelfarsan
@Snorkelfarsan 是的,对于我的测试字符串,它也给出了相同的结果。也许有一些边缘情况涉及到除空格和标点符号之外的其他字符。目前我想不到这样的情况。 - stema
我在每个句子中有时在单词前面加了空格。你能帮我解决这个问题吗? - Vitali Pom

16

有一个非单词字面量,\W,请参见Pattern

String line = "Hello! this is a line. It can't be hard to split into \"words\", can it?";
String[] words = line.split("\\W+");
for (String word : words) System.out.println(word);

提供

Hello
this
is
a
line
It
can
t
be
hard
to
split
into
words
can
it

0

如果你从 Kotlin 的 sentence.split(Regex("[\\p{Punct}\\s]+")) 来到这里


0

感谢您及时回复。这个正则表达式是否表示:在一个或多个周围标点符号的边界内拆分单词? - Snorkelfarsan
好的,正则表达式的意思是匹配一个或多个被单词边界包围的单词字符。问号表示应用非贪婪(懒惰)匹配。 - amal

0

尝试:

line.split("[\\.,\\s!;?:\"]+");
or         "[\\.,\\s!;?:\"']+"

这是一个或匹配其中一个字符的正则表达式:., !;?:"'(请注意其中有一个空格但没有/或\),加号使几个字符一起计算为一个。

这应该可以给您提供大致足够的准确性。更精确的正则表达式需要更多关于您需要解析的文本类型的信息,因为'也可以是单词分隔符。大多数标点符号单词分隔符都在空格周围,因此匹配[\\s]+会是一个接近的近似值。(但在短引语中会给出错误的计数,例如:她说:“不”。)


不幸的是,这给了我比[\p{Punct}\s]+更少的结果。 - Snorkelfarsan
在重新阅读了您最初的帖子后:我误读为您想将“can't”作为一个单词而不是两个单词。请尝试使用:"[.,\s!;?:"']+"。 - Angelo Fuchs
在您的初始帖子中,您使用了[\p{Punct}\s+],在此您在]之后写入+。您能否澄清一些行的期望,请? (例如,我不能。她说:“不”。他是[sic]问题!) - Angelo Fuchs
我把它改成了"]"后面的"+"。无论如何,主要问题不是缺乏正确的正则表达式语法,而是一个string.toLowerCase()调用...单词计数器在我将所有输入转换为小写之前没有将I和i或The和the视为相同的单词。问题解决了。谢谢! - Snorkelfarsan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接