用新行分割Java字符串


388

我正在尝试JTextArea使用正则表达式将文本拆分为,\n但是,这是行不通的,我也尝试了正则表达式的\r\n|\r|n许多其他组合。码:

public void insertUpdate(DocumentEvent e) {
    String split[], docStr = null;
    Document textAreaDoc = (Document)e.getDocument();

    try {
        docStr = textAreaDoc.getText(textAreaDoc.getStartPosition().getOffset(), textAreaDoc.getEndPosition().getOffset());
    } catch (BadLocationException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    split = docStr.split("\\n");
}

7
你得到什么错误?不要说“不起作用”,那没有任何意义。告诉我们您得到的错误/结果。这是调试代码的第一步-找出错误的结果以及程序如何达到此目的。
CHII

你真的想做什么?-在JTextArea中输入行时将其断开?-查找JTextArea在哪里进行换行?-???
user85421

Answers:


731

这应该覆盖您:

String lines[] = string.split("\\r?\\n");

您实际上只需要担心两个换行符(UNIX和Windows)。


43
一个JTextArea文档应该只使用'\ n'; 其视图完全忽略“ \ r”。但是,如果要查找的分隔符不止一种,则最好查找所有三个分隔符:“ \ r?\ n | \ r”。
艾伦·摩尔

10
Mac 9使用\ r。OSX 10使用\ n
Raekye 2013年

$ {fn:length(fn:split(data,'\\ r?\\ n'))}在

4
@antak是的,split默认情况下,如果尾随空字符串发现了分割结果,则将其删除。要关闭此机制,您需要使用split(regex, limit)负数限制的重载版本,例如text.split("\\r?\\n", -1)。更多信息:Java字符串拆分删除了空值
Pshemo '16

1
@stivlo的评论是虚假信息,但不幸的是,它的投票太多。正如@ Raekye指出的那样,OS X(现在称为macOS)自2001年发布以来一直使用\ n作为其行分隔符。MacOS 9于1999年发布,我从未见过使用过Mac OS 9或以下版本的计算机在生产中。没有一个单一的现代操作系统使用\ r作为行分隔符。NEVER写入代码,预计\ r是在Mac行分隔符,除非)你进入复古计算,B)具有OS 9机纺起来,以及c)能够可靠地确定机器实际OS 9是
詹姆斯·麦克劳克林(James McLaughlin)

132

String#split​(String regex)方法是使用正则表达式(正则表达式)。由于Java 8 regex支持\R表示(从Pattern类的文档中):

换行符
\ R任何Unicode换行序列,等效于 \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]

因此我们可以使用它来匹配:

如您所见,\r\n它位于正则表达式的开头,可确保正则表达式首先尝试匹配此,并且仅当匹配失败时,才尝试匹配单个字符行分隔符。


因此,如果要在行分隔符上进行拆分,请使用split("\\R")

如果您不想从结果数组中删除结尾的空字符串,请""使用split(regex, limit)limit参数,例如split("\\R", -1)

如果要将一个或多个连续的空行视为单个定界符,请使用split("\\R+")


4
是的,这是最好的答案。不幸的是,这个问题被提早六年提出了。
达伍德·本·卡里姆

我最后在上\\R+进行了拆分,以避免任何未被\\R单独覆盖的行尾字符。
SeverityOne

128

如果您不希望出现空行:

String.split("[\\r\\n]+")

4
双反斜杠是不必要的,参见“反斜杠,逃逸,并引述” docs.oracle.com/javase/1.4.2/docs/api/java/util/regex/...
angryITguy


1
当上面的答案不起作用时,这在Mac OSX上有效。
约翰

这也为我工作。优秀的解决方案。它适用于以下2种情况:1)我3点钟醒来。\ r \ n \ r \ n我希望2)这是真实生活\ r \ nso
logixplayer

2
@tresf不能在方括号中使用量词。
CX游戏玩家

49
String.split(System.getProperty("line.separator"));

这应该是系统独立的


41
这是一个有趣的想法,但是您应该注意文本实际上使用系统的行分隔符。我在使用“ Windows”分隔符的unix(例如XML)下有很多文本文件,在Windows下使用unix分隔符的文本文件也很多。
Maarten Bodewes 2012年

即使在android上也可以使用
ruX

6
在Windows操作系统中创建并传输到Unix操作系统的文件仍将包含\ r \ n分隔符。我认为最好保持安全并考虑到两个分隔符。
bvdb

17
这是一个非常有问题的方法!该文件可能不是源自运行代码的系统。我强烈反对实际上依赖于特定系统(运行时系统)的这类“与系统无关”的设计。
马丁

4
@Shervin从来没有最好的方法。实际上,这是非常糟糕的做法。考虑其他一些程序员调用System.setProperty(“ line.separator”,“您毫无意义”); 您的代码已损坏。它甚至可能由您不了解的依赖项类似地调用。
马丁

14

linesString课堂上引入了一种新方法,返回 Stream<String>

返回从该字符串中提取的子字符串流,该子字符串由行终止符分隔。

识别的行终止符是换行符“ \ n”(U + 000A),回车符“ \ r”(U + 000D)和回车符,后跟换行符“ \ r \ n”(U + 000D U + 000A )。

这里有一些例子:

jshell> "lorem \n ipusm \n sit".lines().forEach(System.out::println)
lorem
 ipusm
 sit

jshell> "lorem \n ipusm \r  sit".lines().forEach(System.out::println)
lorem
 ipusm
  sit

jshell> "lorem \n ipusm \r\n  sit".lines().forEach(System.out::println)
lorem
 ipusm
  sit

String#lines()


12

您不必在字符组中将转义字符加倍。

对于所有非空行,请使用:

String.split("[\r\n]+")

是的你是。如果他们需要在任何地方进行两次转义,则需要在任何地方进行双重转义。空格转义类似\r\n可以有一个或两个反斜杠;他们以任何一种方式工作。
艾伦·摩尔

2
'\\'代码中的双反斜杠成为'\'字符,然后传递给RegEx引擎,因此"[\\r\\n]"代码[\r\n]中的双反斜杠进入内存,RegEx将对其进行处理。我不知道Java如何精确地处理RegEx,但是将“纯” ASCII字符串模式传递给RegEx引擎并让其进行处理而不是传递二进制字符是一种很好的做法。"[\r\n]"变成(十六进制)0D0A在内存中,一个RegEx引擎可能会接受它,而另一个则会阻塞。因此,最重要的是,即使Java风格的RegEx不需要它们,
也要

10

JDK11所述String类有一个lines()方法:

返回从此字符串中提取的行流,以行终止符分隔。

此外,文档继续说:

行终止符是以下之一:换行符“ \ n”(U + 000A),回车符“ \ r”(U + 000D)或回车符后紧跟换行符“ \ r \ n“(U + 000D U + 000A)。一行是零个或多个字符的序列,后跟一个行终止符,或者是一个或多个字符的序列,后跟字符串的结尾。一行不包括行终止符。

有了这个,就可以做到:

Stream<String> stream = str.lines();

然后,如果您想要一个数组:

String[] array = str.lines().toArray(String[]::new);

给定此方法后,Stream将为您提供很多选择,因为它使您能够编写可能并行操作的简洁声明式表达式。


7

也许这会工作:

从split方法的参数中删除双反斜杠:

split = docStr.split("\n");

8
并不是的。当您以Java String文字形式编写正则表达式时,可以使用“ \ n”向正则表达式编译器传递换行符,或使用“ \\ n”向其传递换行符的转义序列。除\ v以外,其他所有空白转义符也是如此,Java文字不支持。
艾伦·摩尔

3
@Yuval。抱歉,这是不正确的,您根本不需要“反斜杠,转义和引用” docs.oracle.com/javase/1.4.2/docs/api/java/util/regex / ...
AngryITguy 2011年

7

实际上,这里给出的所有答案都不符合Java对新行的定义,例如BufferedReader#readline。Java正在接受\n\r并将其\r\n作为新行。一些答案匹配多个空行或格式错误的文件。例如。<sometext>\n\r\n<someothertext>使用时[\r\n]+将导致两行。

String lines[] = string.split("(\r\n|\r|\n)", -1);

相反,以上答案具有以下属性:

  • 它符合Java对新行的定义,例如BufferedReader正在使用它
  • 它与多个新行不匹配
  • 它不会删除尾随的空行

6

如果由于某种原因而不想使用String.split(例如,由于使用正则表达式),并且想要在Java 8或更高版本上使用函数式编程,请执行以下操作:

List<String> lines = new BufferedReader(new StringReader(string))
        .lines()
        .collect(Collectors.toList());

我知道这可能是一个过大的解决方案。
Danilo Piazzalunga

3
String[] lines = new BufferedReader(...).lines().toArray(String[]::new);用于数组而不是列表。这个解决方案的好处是BufferedReader知道各种终止符,因此它可以处理各种格式的文本。(此处发布的大多数基于正则表达式的解决方案在这方面均
达不到要求

2
自从Java 11和引入String.lines()方法以来,该解决方案就已经过时了。
leventov '18 -10-4

4

为了防止空行被压扁,请使用:

String lines[] = String.split("\\r?\\n", -1);

3

上面的代码实际上并没有做任何可见的事情-它只是计算出来然后转储计算。是您使用的代码,还是该问题的一个示例?

尝试在最后做textAreaDoc.insertString(int,String,AttributeSet)?


insertUpdate()是一个DocumentListener方法。假设OP使用正确,尝试从侦听器方法中修改文档将产生异常。但是您是对的:该问题中的代码实际上没有执行任何操作。
艾伦·摩尔

2

Splitter如果要对结果行执行其他操作(例如修剪行或过滤空行),则可以使用guava的API 替代以前的答案:

import com.google.common.base.Splitter;

Iterable<String> split = Splitter.onPattern("\r?\n").trimResults().omitEmptyStrings().split(docStr);

请注意,结果是an,Iterable而不是数组。



1

经过失败尝试后,基于所有给定的解决方案。我\n用一些特殊的词代替,然后拆分。对我来说,下面的技巧:

article = "Alice phoned\n bob.";
article = article.replace("\\n", " NEWLINE ");
String sen [] = article.split(" NEWLINE ");

我无法复制问题中给出的示例。但是,我猜想可以应用这种逻辑。



0
  • 试试这个希望对您有帮助的希望

 String split[], docStr = null;
Document textAreaDoc = (Document)e.getDocument();

try {
    docStr = textAreaDoc.getText(textAreaDoc.getStartPosition().getOffset(), textAreaDoc.getEndPosition().getOffset());
} catch (BadLocationException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
}

split = docStr.split("\n");

0

共有三种不同的约定(可以说是 设置和显示换行符事实上的标准):

  • carriage return + line feed
  • line feed
  • carriage return

在某些文本编辑器中,可以将一个交换为另一个:

记事本++

最简单的事情是将其规格化line feed然后拆分。

final String[] lines = contents.replace("\r\n", "\n")
                               .replace("\r", "\n")
                               .split("\n", -1);

0

镇上有一个新男孩,所以您不必处理所有上述复杂性。 从JDK 11开始,只需编写为单行代码,它将拆分行并返回String流。

public class MyClass {
public static void main(String args[]) {
   Stream<String> lines="foo \n bar \n baz".lines();
   //Do whatever you want to do with lines
}}

一些参考。 https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#lines() https://www.azul.com/90-new -jdk-11中的功能和api /

我希望这会对某人有所帮助。快乐的编码。


-1
package in.javadomain;

public class JavaSplit {

    public static void main(String[] args) {
        String input = "chennai\nvellore\ncoimbatore\nbangalore\narcot";
        System.out.println("Before split:\n");
        System.out.println(input);

        String[] inputSplitNewLine = input.split("\\n");
        System.out.println("\n After split:\n");
        for(int i=0; i<inputSplitNewLine.length; i++){
            System.out.println(inputSplitNewLine[i]);
        }
    }

}

与其他答案相比,它们显得苍白无力,后者更具解释性且代码量少。您能否解释一下用此代码完成的工作,以及为什么它会给出合适的答案?
Makoto 2014年

2
这与将文件分割成几行无关。考虑删除您的答案。
马丁
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.