При сопоставлении определенных символов (например, строки) вы можете использовать регулярное выражение "\\n" или просто "\n". Например, следующее разбиение строки на массив строк:
String[] lines = allContent.split("\\r?\\n");
Но следующее работает так же хорошо:
String[] lines = allContent.split("\r?\n");
Мой вопрос:
Выполняете ли эти два действия точно так же, или есть какая-то тонкая разница? Если последнее, можете ли вы привести примерный случай, когда вы получите разные результаты?
Или существует ли разница только в [возможной/теоретической] производительности?
В текущем сценарии нет никакой разницы. Обычные последовательности escape-последовательности строки формируются с помощью одного обратного слэша, а затем действительный escape-символ ("\n"
, "\r"
и т.д.), А управляющие последовательности регулярных выражений формируются с помощью буквальной обратной косой черты (то есть, двойная обратная косая черта в строковом литерале Java) и действительный символ escape regex ("\\n"
, "\\d"
и т.д.).
"\n"
(escape-последовательность) - это буквальная LF (новая строка), а "\\n"
- это escape-последовательность регулярного выражения, которая соответствует символу LF.
"\r"
(escape-последовательность) представляет собой литерал CR (возврат каретки), а "\\r"
- последовательность escape-выражений регулярного выражения, которая соответствует символу CR.
"\t"
(escape-последовательность) является символом символа табуляции, а "\\t"
является управляющей последовательностью регулярного выражения, которая соответствует символу табуляции.
См. Список в документах Java regex для поддерживаемого списка экранов регулярных выражений.
Тем не менее, если вы используете флаг Pattern.COMMENTS
(используется для представления комментариев и форматирования рисунка красиво, заставляя механизм регулярных выражений игнорировать все незаметные пробелы в шаблоне), вам нужно либо использовать "\\n"
либо "\\\n"
для определения новой строки (LF) в строковом литерале Java и "\\r"
или "\\\r"
для определения возврата каретки (CR).
См. Тест Java:
String s = "\n";
System.out.println(s.replaceAll("\n", "LF")); // => LF
System.out.println(s.replaceAll("\\n", "LF")); // => LF
System.out.println(s.replaceAll("(?x)\\n", "LF")); // => LF
System.out.println(s.replaceAll("(?x)\\\n", "LF")); // => LF
System.out.println(s.replaceAll("(?x)\n", "<LF>"));
// => <LF>
//<LF>
Почему последний производит <LF>
+ новую строку + <LF>
? Поскольку "(?x)\n"
равно ""
, пустой шаблон, и он соответствует пустому пространству перед новой строкой и после него.
Да, есть разные. Компилятор Java имеет другое поведение для Unicode Escapes
в разделе Java Book The Java Language
Specification section 3.3;
Язык программирования Java определяет стандартный способ преобразования программа, написанная в Unicode в ASCII, которая изменяет программу на форма, которая может обрабатываться инструментами на основе ASCII. Преобразование включает в себя преобразование любых экранов Unicode в исходный текст программы в ASCII, добавив дополнительный u - например, \uxxxx становится \ uuxxxx - при одновременном преобразовании несимвольных символов в исходный текст для экранов Unicode, содержащих один u каждый.
Итак, как это влияет на /
n vs //n
в Java Doc:
Поэтому необходимо удвоить обратную косую черту в строковых литералах которые представляют собой регулярные выражения для защиты их от интерпретации с помощью компилятора байт-кода Java.
Пример одного документа:
Строковый литерал "\ b", например, соответствует одному обратному пространству символ, интерпретируемый как регулярное выражение, тогда как "\ b" соответствует границе слова. Строковый литерал "(привет)" является незаконным и приводит к ошибке времени компиляции; чтобы соответствовать строке (привет) необходимо использовать строковый литерал "\ (hello \)".
"\\"
для определения одиночной обратной косой черты в строковых литералах Java. Вопрос OP заключается в том, совпадают ли "\n"
и "\\n"
одинаковые строки. Хотя шаблоны отличаются, они соответствуют одному и тому же тексту. Вот почему я говорю, что в текущем сценарии нет никакой разницы .
\\n
соответствует LF,\n
соответствует LF.