Что такое перекрестное платформенное выражение для удаления разрывов строк?

Я уверен, что это было задано раньше, но я не могу его найти.

В принципе, если вы разбираете текстовый файл неизвестного происхождения и хотите заменить разрывы строк каким-либо другим разделителем, является ли это лучшим регулярным выражением или есть другой?

(\r\n)|(\n)|(\r)

Ответы

Ответ 2

Проверьте, поддерживает ли ваш механизм regex \R в виде сокращенного символьного класса, и вам не нужно будет беспокоиться о различных комбинациях Unicode newline/linefeed. Если они выполнены правильно, вы можете прозрачно сопоставлять все различные контуры ascii или Unicode, используя \R.

В Unicode вам нужно обнаружить NEL (конец строки OS/390,\x85) LS (разделитель строк, \x2028) и PS (разделитель абзацев, \x2029), если вы хотите полностью пересечь платформе в эти дни.

Это спорно ли LS, NEL, и PS следует рассматривать как разрыв строки, строки окончания или белое пространство. Стандарт XML 1.0, например не распознает NEL как символ прерывания строки. ECMAScript рассматривает LS и PS как разрывы строк, но NEL как пробельные символы. Perl unicode regexs будет обрабатывать VT, FF, CR, CRLF, NEL, LS и PS как разрывы строк для метасимволов ^ и $ regex.

Руководство по внедрению Unicode (раздел 5.8 и таблица 5.3), вероятно, лучший выбор того, какое окончательное отношение к тому, что означает "новая линия",

Если вас интересует только ascii с вариантами классического DOS/Windows/Unix/Mac, эквивалент регулярного выражения \R равен (?>\r\n|[\r\n])

В Unicode эквивалент \R равен (?>\r\n|\n|\x0b|\f|\r|\x85|\x2028|\x2029) \x0b, там есть вертикальная вкладка; еще раз, это может или не может соответствовать вам определение того, что разрыв строки, но это соответствует рекомендации Unicode Implantation. (FF или \x0C не входит в регулярное выражение, так как Feed Feed - это новая страница, а не новая строка в определении.)

Ответ 3

Регулярное выражение для поиска любого ограничителя строки Юникода должно быть (?>\x0D\x0A?|[\x0A-\x0C\x85\x{2028}\x{2029}]) скорее чем писал дрюк, по крайней мере, в Perl. Взято непосредственно из perl 5.10.0 (она была удалена в более поздних версиях). Обратите внимание на фигурные скобки после \x: U + 2029 \x{2029} но \x2029 - пробел ASCII (U + 0020) + цифра 2 + a знака 9. \n вне класса символов, также не гарантируется соответствие \x{0a}.

Ответ 4

Если ваша платформа не поддерживает класс \R, как указано в @dawg выше, вы все равно сможете сделать довольно элегантное и надежное решение, если ваша платформа поддерживает отрицательный lookaround или вычитание символьного класса (например, в вычитании класса Java через синтаксис [x&&[^y]]).

В большинстве регулярных выражений грамматики символ точки определяется как "любой символ, кроме символа новой строки" (см., например, для JavaScript, здесь). Если вы сопоставляете что-то со следующими характеристиками:

  • нет (любой символ, кроме символа новой строки) → символ новой строки; и
  • - пробел.

Поскольку я сейчас работаю в JavaScript, у AFAIK нет вычитания стенографического или символьного класса \R, я все же могу использовать отрицательный просмотр, чтобы получить то, что я хочу. Следующее регулярное выражение соответствует всем новым строкам:

/((?!.)\s)+/g

И следующий код JavaScript, по крайней мере, когда он запущен в Chrome 42.0.2311.90m в Windows 7, уничтожает все типы новых строк, которые JavaScript (то есть "ECMAScript", упомянутый в третьем абзаце @dawg) распознает:

var input = "hello\r\n\f\v\u2028\u2029 world";
var output = input.replace(/((?!.)\s)+/g, "");
document.write(output); // hello world

Ответ 5

Просто замените /[\r\n]+/g пустой строкой "".

Он заменит все \r и \n независимо от того, какой порядок они отображаются в строке.