【问题标题】:use of delimiter function from scanner for "abc-def"对“abc-def”使用扫描仪的分隔符功能
【发布时间】:2009-04-15 09:11:49
【问题描述】:

我目前正在尝试过滤包含用“-”分隔的单词的文本文件。我要数字数。

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

简单的问题是:包含“-”的单词将被分开并计为两个单词。所以只是用 \- 转义不是首选的解决方案。

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

谢谢 ;)

【问题讨论】:

  • 这个不太清楚,能不能放一些你想要什么不想要什么的样本?
  • @chburd:我认为他希望“一二三四”是三个词。

标签: java regex java.util.scanner text-formatting


【解决方案1】:

好的,我在这里猜你的问题:你的意思是你有一个包含一些“真实”散文的文本文件,即实际上有意义的句子,用标点符号等分隔,对吧?

例子:

据我们所知,这种情况得到了改善,因为我们最信任的盟友 Vorgons 继续举办他们的诗歌大满贯比赛;敌人几乎没有动机去干涉,即使他们的 Mute-O-Matic 设备也是如此。

因此,您需要的分隔符可以是任意数量的空格和/或标点符号(您已经用显示的正则表达式涵盖了这些),或者是每边至少被一个空格包围的连字符. “或”的正则表达式字符是“|”。在许多正则表达式实现中,空白字符类(空格、制表符和换行符)都有一个快捷方式:“\s”。

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

【讨论】:

    【解决方案2】:

    如果可能,请尝试使用预定义的类...使正则表达式更易于阅读。有关选项,请参阅 java.util.regex.Pattern。

    也许这就是你要找的东西:

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

    读取:匹配 1 个或多个空白字符,可选地后跟零个或多个非单词字符和一个空白字符。

    【讨论】:

    • 我还应该指出,正则表达式模式需要双重转义,否则编译器会抱怨 \foo 不是有效的字符串字符。
    【解决方案3】:

    这不是很简单。要尝试的一件事是 {current-delimeter-chars}{zero-or-more-hyphens}{zero-or-more-current-delimeter-chars-or-hyphen}。

    忽略扫描仪返回的完全由连字符组成的单词可能更容易

    【讨论】:

      【解决方案4】:
      Scanner scanner = new Scanner("one   two2  -   (three) four-five - ,....|");
      scanner.useDelimiter("(\\B+-\\B+|[.,:;()?!\" \t|])+");
      
      while (scanner.hasNext()) {
          System.out.println(scanner.next("\\w+(-\\w+)*"));
      }
      

      注意

      next(String) 方法断言你只得到单词,因为原来的 useDelimiter() 方法错过了“|”

      注意

      您已使用正则表达式“\r\n|\n”作为行终止符。 java.util.regex.Pattern 的 JavaDocs 显示了其他可能的行终止符,因此更完整的检查将使用表达式 "\r\n|[\r\n\u2028\u2029\u0085]"

      【讨论】:

      • \B 是零宽度断言;它匹配不是单词边界的位置。它不消耗任何字符,因此添加“+”或任何其他量词是没有意义的。 Java 只是忽略了量词,但其他一些正则表达式风格将其视为语法错误。
      • 另外,OP 没有使用“\r\n|\n”。他根本对行分隔符不感兴趣。他只是将最常见的空白字符与字符类中的标点字符匹配(但他应该使用“\s”,就像@Svante 所做的那样)。
      • 他在 useDelimiter() 中使用了 \r\n,顺便说一句,感谢您的第一次澄清! :)
      【解决方案5】:

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

      • 当然,如果是散文,并且您想排除 下划线
        [^\\p{Alnum}-]\\P{Alnum}*|-\\P{Alnum}+
      • 或者如果您不希望使用数字:
        [^\\p{Alpha}-]\\P{Alpha}*|-\\P{Alpha}+

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

      【讨论】:

        猜你喜欢
        • 2014-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多