Что такое кросс-платформенное регулярное выражение для удаления разрывов строк?
Я уверен, что об этом уже спрашивали, но я не могу его найти.
В основном, если вы анализируете текстовый файл неизвестного происхождения и хотите заменить разрывы строк каким-либо другим разделителем, это лучшее регулярное выражение или есть другой?
(\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, здесь). Если вы соответствуете что-то со следующими характеристиками:
- нет (любой символ, кроме символа новой строки) → символ новой строки; а также
- это пробел
Так как в настоящее время я работаю в 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
независимо от того, в каком порядке они появляются в строке.