Java разделяет строку с '\ r \ n', '\ r' или '\ n' и сохраняет ее с предыдущей подстрокой - PullRequest
3 голосов
/ 08 апреля 2019

Моя входная строка содержит разделители строк смешанного типа, включая «\ r \ n», «\ r» или «\ n».Я хочу разделить строку и сохранить разделитель строк с подстрокой, которая предшествует ей.Я следовал за двумя сообщениями ниже

Как разбить строку, но также сохранить разделители?

Разделить строку Java по новой строке

и придумайте что-то вроде:

String input = "1 dog \r\n 2 cat";
String[] output = input.split( "(?<=((\\r\\n)|\\r|\\n))")));

на выходе будет ["1 dog\r", "\n", " 2 cat"], однако желаемый результат будет ["1 dog\r\n", " 2 cat"].

Если я изменю вход на String input = "1 dog \r 2 cat"; или String input = "1 dog \n 2 cat";, мой код может выдавать желаемый результат.Пожалуйста, порекомендуйте.Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 08 апреля 2019

Вы получите свой результат ["1 dog\r", "\n", " 2 cat"], потому что ваш шаблон использует чередование, которое будет соответствовать либо (\r\n), либо \r, либо \n.

При обнаружении \r\n в строке примера утверждение lookbehind будет истинным после \r и будет впервые разделено.

Тогда утверждение lookbehind будет истинным после \n и разделится во второй раз.

То, что вы можете сделать, это использовать \R в положительном виде, чтобы утверждать, что слева есть последовательность символов новой строки * unicode :

String input = "1 dog \r\n 2 cat";
String[] output = input.split("(?<=\\R)");

Демонстрация Java

Другой вариант исправления вашего регулярного выражения - сделать его атомной группой :

(?<=(?>\\r\\n|\\r|\\n))

Демонстрация Java

Чтение этого поста , когда \r сопоставляется в структуре взгляда с использованием атомарной группы, следующее \n также сопоставляется.

1 голос
/ 08 апреля 2019

Если вы используете следующее регулярное выражение: (?<=\\r\\n|\\r(?!\\n)|\\n), чтобы разделить вашу строку, она будет работать как задумано.

То, что происходит с вашим регулярным выражением, заключается в том, что когда встречается \r\n, утверждение обратного взгляда будет истинным (?<=\r) и будет разбивать строку сразу после \r.

Вот почему я добавил отрицательный прогноз (?!\n) после \r, чтобы убедиться, что символ после \r не \n. Это предотвратит разрыв между \r и \n и сохранит его в целом.

Демонстрация: https://regex101.com/r/H6PNmY/1/ (где я заменил \r на a и \n на b для удобства чтения)

Когда вы вставите это обратно в свой код:

String input = "1 dog \r\n 2 cat, 1 car \r 2 planes, 1 apple \n 2 peaches";
String[] output = input.split("(?<=\\r\\n|\\r(?!\\n)|\\n)");

for(int i=0; i<output.length; i++)
{
  printASCII(output[i]);
  System.out.println("===");        
}

с printASCII определяется как:

public static void printASCII(String in)
{
    for(int i=0; i<in.length(); i++)
        System.out.println("The ASCII value of " + in.charAt(i) + "  =  " + (int)in.charAt(i) );
}

Это дает вам следующий вывод:

The ASCII value of 1  =  49
The ASCII value of    =  32
The ASCII value of d  =  100
The ASCII value of o  =  111
The ASCII value of g  =  103
The ASCII value of    =  32
The ASCII value of 
  =  13
The ASCII value of 
  =  10
===
The ASCII value of    =  32
The ASCII value of 2  =  50
The ASCII value of    =  32
The ASCII value of c  =  99
The ASCII value of a  =  97
The ASCII value of t  =  116
The ASCII value of ,  =  44
The ASCII value of    =  32
The ASCII value of 1  =  49
The ASCII value of    =  32
The ASCII value of c  =  99
The ASCII value of a  =  97
The ASCII value of r  =  114
The ASCII value of    =  32
The ASCII value of 
  =  13
===
The ASCII value of    =  32
The ASCII value of 2  =  50
The ASCII value of    =  32
The ASCII value of p  =  112
The ASCII value of l  =  108
The ASCII value of a  =  97
The ASCII value of n  =  110
The ASCII value of e  =  101
The ASCII value of s  =  115
The ASCII value of ,  =  44
The ASCII value of    =  32
The ASCII value of 1  =  49
The ASCII value of    =  32
The ASCII value of a  =  97
The ASCII value of p  =  112
The ASCII value of p  =  112
The ASCII value of l  =  108
The ASCII value of e  =  101
The ASCII value of    =  32
The ASCII value of 
  =  10
===
The ASCII value of    =  32
The ASCII value of 2  =  50
The ASCII value of    =  32
The ASCII value of p  =  112
The ASCII value of e  =  101
The ASCII value of a  =  97
The ASCII value of c  =  99
The ASCII value of h  =  104
The ASCII value of e  =  101
The ASCII value of s  =  115
===

Это показывает, что символы EOL правильно сохраняются, как вы и просили.

ASCII таблица: https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/com.ibm.aix.networkcomm/conversion_table.htm

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...