【问题标题】:String tokenization in java (LARGE text)java中的字符串标记化(大文本)
【发布时间】:2023-04-06 02:33:01
【问题描述】:

我有这个大文本(阅读大)。我需要标记每个单词,分隔每个非字母。我使用 StringTokenizer 一次读取一个单词。但是,当我正在研究如何编写分隔符字符串(“每个非字母”)而不是执行以下操作时:

new StringTokenizer(text, "\" ();,.'[]{}!?:”“…\n\r0123456789 [etc etc]");

我发现基本上每个人都讨厌 StringTokenizer(为什么?)。

那么,我可以用什么代替呢?不要建议 String.split 因为它会复制我的大文本。我需要逐字阅读文本并为每个非字母定界。自己构建一些东西更容易还是有一些最佳实践方法来解决这个问题?

提前致谢!

【问题讨论】:

  • 你的文字有多大,真的吗?它适合内存吗?

标签: java string tokenize stringtokenizer large-data


【解决方案1】:

StringTokenizer,根据文档 "StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead." 这几乎总结了 StringTokenizer 的仇恨。

如果内存真的很重要,您可以逐个字符地遍历字符串和分隔符之间的子字符串,进行处理,然后继续。

【讨论】:

  • 也就是说,我自己构建一些东西。是的,猜猜这就是我必须做的。
【解决方案2】:

您可以使用来自 Google 的 库的灵活字符串 Splitter 类。

如果您需要更强大的功能,请查看来自 Apache Lucene 的 StandardTokenizer。 来自文档:

这对于大多数欧洲语言文档来说应该是一个很好的标记器:

  • 在标点符号处拆分单词,删除标点符号。但是,后面没有空格的点被认为是 一个令牌。
  • 在连字符处拆分单词,除非标记中有数字,在这种情况下,整个标记被解释为产品编号并且是 不拆分。
  • 将电子邮件地址和互联网主机名识别为一个令牌。

【讨论】:

    【解决方案3】:

    如果你的语法复杂,文件很大,你可以考虑使用JavaCC

    当我遇到你的情况时,我会使用它。

    【讨论】:

      【解决方案4】:

      Scanner.class 逐字(或逐行)读取,可用于大文件(或输入流)。

      Pattern for RegEx 可以检测空间和很多东西(看看 § 你可以在哪里找到类似 \p{..}

      【讨论】:

        【解决方案5】:

        我从来都不是正则表达式的粉丝,但我看不出仅将"[^a-zA-Z]" 用于 StringTokenizer 有什么问题。

        【讨论】:

        • StringTokenizer 中的分隔符字符串未编译为正则表达式。所以它不会工作。
        猜你喜欢
        • 1970-01-01
        • 2018-09-12
        • 2013-07-28
        • 1970-01-01
        • 2018-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多