Java中可以用什么字符来解析段落?

8
我相信大家都会对这个问题感到好笑,但是我却无法找到一个分隔符来指示文本字符串中新段落的开始。在文字和行末添加分隔符很容易,但是要找到段落就比较困难了。我已经尝试过两个换行符、段落分隔符和换行符的Unicode表示,但都没能成功。
编辑:我为我的原始问题含糊不清而道歉。回答一些问题,它是一个最初在Windows上创建的基本文本文件。我正在使用Blackberry JDE 4.5测试一些打开和分析其内容的代码,并使用RIM Eclipse插件。虽然文件的来源将是Windows(至少在可预见的未来),并且是基本文本,但我无法控制它们的创建方式(它是一个第三方源,我无法访问创建方式)。

这个角色的受众是谁? - bmargulies
我喜欢使用字符串“I'm a new paragraph”作为分隔符。使用任何不会干扰其他部分的内容。 - Aiden Bell
@Aiden - 你在句子中间加了一个段落分隔符。在单词 "string" 后面。希望有帮助 :-) - Stephen C
也许您需要更详细地阐述“段落”。例如,这段文本来自哪里?您是否有示例文本和所需结果的示例?您实际上是不是指“句子”? - BalusC
你打算如何使用这些段落? - Gladwin Burboz
显示剩余3条评论
6个回答

5
常用中没有这样的段落分隔符。您可以假设连续两个或多个换行符(可带水平空格)表示段落分隔符,但是有许多例外情况。例如,当一个段落被浮动图像打断或包含项目符号时,就像这个例子一样,然后继续... 对于这种情况,可能没有解决方案。
根据@Aiden下面的评论进行编辑。 (现在清楚了,这与OP无关,但它可能与通过Google等找到问题的其他人有关)
不要试图从文本中反向工程出段落,也许您应该考虑指定您的输入格式为(例如)Markdown语法;即由StackOverflow支持。 Markdown Wiki包括许多语言中的markdown解析器实现的链接,包括Java。
(这假设您对要解析为段落等的文本的输入格式具有一定的控制。)

也许他需要指向一个基本的Java markdown解析器的方向? - Aiden Bell

5
在普通文本文档中,段落通常由两个或多个行分隔符分开。行分隔符可以是一个换行符(\n)、回车符(\r)或回车符后跟一个换行符(\r\n)。这三种分隔符通常与操作系统相关联,但任何应用程序都可以自由地使用任何类型的行分隔符来编写文本。事实上,从不同来源(如网页)汇集起来的文本可能包含两种或更多种分隔符。当您的应用程序读取文本时,无论在哪个平台上运行,它都应始终检查所有三种行分隔符。 BufferedReader#readLine() 实现了这一点,但它一次只能读取一行。简单的散文通常被作为非空行交替返回,表示段落,而空行则表示它们之间的空格。但是不要指望它;注意多个空行,并意识到“空”行实际上可能包含空格字符,如空格 (\u0020) 和制表符 (\u0009)。
如果您选择不使用 BufferedReader,则必须从头开始编写检测代码。Java ME 不包括正则表达式支持,因此split()java.util.Scanner 不可用;而 StringTokenizer 不能区分单个分隔符字符和多个连续的分隔符字符,除非使用 returnDelims 选项。然后它会一次返回一个字符作为分隔符,因此您仍然需要编写自己的代码来确定您正在查看哪种类型的分隔符(如果有)。

3

有可能需要查找CR LF序列(\r\n)而不是换行符-显然,答案取决于文本格式。


2
String lineSeparator = System.getProperty("line.separator");

该函数返回平台默认的换行符。

例如,以下代码应该能正常工作:

String[] paragraphs = text.split(lineSeparator);

只有当line.separator仅用于新段落时,此方法才有效,但这并不一定是情况。 - sleske
它还假定生成文本的系统使用与运行代码的系统相同的分隔符。 - Pete Kirkham
完全正确。原帖作者必须更清楚地阐明功能需求和实际问题。然而,这个模糊的问题足够让我提供这个答案。 - BalusC
很抱歉在这个问题上表述不够清楚。尝试了这个解决方案...发现它阻止了应用程序的启动(或直接崩溃)。我想这就是测试版JDE的乐趣吧。 - canadiancreed

2
我假设您有一个文本文件,而不是像MS-Word或RTF这样的复杂文档。
文本文档中“段落”概念并没有定义得很好。大多数情况下,新段落将通过打开文本编辑器时,您会看到下一组文本在下一行开始来识别。
有两个特殊字符,即换行符(LF-'\n')和回车符(CR-'\r'),会导致文本在下一行开始。使用哪个字符来换行取决于您使用的操作系统。此外,有时还会使用两者的组合,如CRLF('\r\n')。
在Java中,您可以使用System.getProperty("line.separator");来确定用于分隔行/段落的字符或字符集。但是这带来了一个新问题。如果您在MS Windows中创建一个文本文件,然后在Unix中打开它,那么文本文件中的行分隔符就是Windows的行分隔符,但Java正在运行Unix上。 我的建议是:

如果文本长度(文件大小)为零,则段落=0。

如果文本长度(文件大小)不为零,则

  • '\n''\r'视为换行符
  • 扫描您的文本以查找上述换行符。
  • 任何连续的以任何顺序出现的换行符都应视为一个段落分隔符
  • 段落数= 1 +(段落分隔符计数)
请注意,Stephen指出的异常在此处也适用。
public class ParagraphTest {

    public static void main(String[] args) {
        String document = 
                    "Hello world.\n" + 
                    "This is line 2.\n\r" + 
                    "Line 3 here.\r" + 
                    "Yet another line 4.\n\r\n\r" + 
                    "Few more lines 5.\r";
        printParaCount(document);
    }

    public static void printParaCount(String document) {
        String lineBreakCharacters = "\r\n";
        StringTokenizer st = new StringTokenizer(
                    document, lineBreakCharacters);
        System.out.println("ParaCount: " + st.countTokens());
    }

}

输出

ParaCount: 5

2
首先,您最好定义一个段落。无论是换行、双倍行距还是换行后跟制表符。假设您无法控制输入并想确定各种文本样本中的段落数量,可能存在任何这些情况。此外,它们可能在同一文档中用于相同的目的。因此,需要进行一些分析,并记住它不会始终100%准确。
首先初始化各种可能的段落分隔符:
- "\r" - "\n\r" - "\n" - System.getProperty("line.seperator") - 所有这些内容,但两次,以及所有那些以额外的制表符('\t')结尾的变化。
低效的方法是将输入加载到字符串中,然后调用buffer.split().length来确定有多少个段落。高效、可伸缩的方法是使用一个流,遍历输入,考虑段落的长度,并丢弃那些低于给定“阈值”的段落。更高级的算法甚至可能在遇到处理换行的方式切换后改变其认为是段落的方式(例如几个非常短的行或几个非常长的行)。
而且,所有这些都假定您正在处理没有章节标题等格式的文本。归根结底,询问特定文本中有多少个段落的概念就像询问一年有多少周一样。它不完全是52,但大致在那里。

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