我目前正在尝试过滤一个文本文件,其中包含用“-”分隔的单词。我想数一下字数。

scanner.useDelimiter(("[.,:;()?!\" \t\n\r]+"));

发生的问题很简单:包含“-”的单词将被分隔并计为两个单词。所以仅仅用 \- 转义并不是选择的解决方案。

如何更改分隔符表达式,以便保留“foo-bar”之类的单词,但单独的“-”将被过滤掉并忽略?

谢谢 ;)

有帮助吗?

解决方案

OK,我猜在这里你的问题:你的意思是你有一些“真正的”散文的文本文件,即句子实际意义,标点符号等,等分开吧“? / p>

示例:

  

此情况改善 - 据我们所知 - 的事实,我们最值得信赖的盟友Vorgons,继续持有他们的诗歌大满贯比赛;敌人有少许刺激干扰的是,甚至与他们静音-O-Matic的设备。

因此,需要作为分隔符是什么东西,或者是空白和/或标点(你已经覆盖有你表现出正则表达式)的任何量,或由至少一个空白包围每一侧上的连字符。对正则表达式字符“或”是“|”。有许多regex实现为空白字符类的快捷方式(空格,制表符,和换行):“\ S”

"[.,:;()?!\"\s]+|\s+-\s+"

其他提示

如果可能尽量使用预先定义的类...使得正则表达式更容易阅读。见java.util.regex.Pattern中为选项。

这也许是你在找什么:

string.split("\\s+(\\W*\\s)?"

读取:第1场或多个空白字符任选地接着是零个或多个非字字符和一个空白字符

这是不是很简单。有一点要尝试将是{电流定界符-字符} {零或更多的连字符} {零或更多的电流 - 定界符-字符或 - 连字符}。

有可能更容易忽略由完全的连字符由扫描器返回字

Scanner scanner = new Scanner("one   two2  -   (three) four-five - ,....|");
scanner.useDelimiter("(\\B+-\\B+|[.,:;()?!\" \t|])+");

while (scanner.hasNext()) {
    System.out.println(scanner.next("\\w+(-\\w+)*"));
}

<强> NB

下一个(String)方法断言,你唯一的话,因为原来的useDelimiter()方法未命中“|”

<强> NB

已使用正则表达式为 “\ r \ n | \ n” 个作为行终止符。为java.util.regex.Pattern中的Javadoc示出其它可能的行终止符,所以更完整的检查将使用表达式为 “\ r \ n | [\ r \ n \ u2028 \ u2029 \ u0085]”

这应该很简单: [^\\w-]\\W*|-\\W+

  • 但当然,如果它是散文,而你想排除 下划线:
    [^\\p{Alnum}-]\\P{Alnum}*|-\\P{Alnum}+
  • 或者如果您不期望数字:
    [^\\p{Alpha}-]\\P{Alpha}*|-\\P{Alpha}+

编辑: 这些是更简单的形式。请记住,完整的解决方案将遵循这种模式,处理行首和行尾的破折号。 (?:^|[^\\w-])\\W*|-(?:\\W+|$)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top