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

Я уверен, что об этом уже спрашивали, но я не могу его найти.

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

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

5 ответов

Решение

Флетчер - об этом однажды спросили.

Здесь вы идете: регулярное выражение для соответствия кросс-платформенных символов новой строки

  • Осторожно, спойлеры!

Когда я хочу быть точным, я использую регулярное выражение "\r\n?|\ N".

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

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

Это спорно ли LS, NEL, и PS следует рассматривать как разрыв строки, строки окончания или белое пространство. Например, стандарт XML 1.0 не распознает NEL как символ перевода строки. ECMAScript лечит LS а также PS как разрывы строк, но NEL как пробел. Регулярные выражения в Perl VT, FF, CR, CRLF, NEL, LS а также PS как разрывы строк с целью ^ а также $ регулярные выражения мета-символов.

Руководство по внедрению 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. (FF, или же \x0C не включается в регулярное выражение, поскольку фид форм - это новая страница, а не новая строка в определении.)

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

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

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

  1. нет (любой символ, кроме символа новой строки) → символ новой строки; а также
  2. это пробел

Так как в настоящее время я работаю в 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

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

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

Другие вопросы по тегам