Збіг рядкових розривів - \ n чи \ r \ n?


159

Під час написання цієї відповіді мені довелося співставляти виключно на sпроривах рядків, а не використовувати -flag ( dotall- крапка збігів рядків).

Сайти, які зазвичай використовуються для тестування регулярних виразів, поводяться по-різному при спробі відповідності на \nабо \r\n.

Я помітив

  • Regex101 відповідає лише рядковим розривам \n
    ( приклад - видалення \rта збіг)

  • RegExr не відповідає ні на, \n ні ввімкнено, \r\n
    і я не можу знайти щось для того, щоб воно mзбігалося з розривом рядків, за винятком -flag та \s
    ( приклад )

  • Debuggex поводиться ще більше:
    у цьому прикладі він відповідає лише увімкнено \r\n, тоді як
    тут він відповідає лише тому \n, що вказані ті самі прапорці та двигун

Я цілком усвідомлюю m-flag (багаторядковий - поєднує ^початок і $кінець рядка), але іноді це не варіант. Те саме \s, що відповідає вкладкам і пробілам.

Моя думка використовувати символ unicode newline ( \u0085) виявилася невдалою, тому:

  1. Чи є безпечний спосіб інтегрувати відповідність у рядку (бажано незалежно від мови, що використовується) у регулярний вираз?
  2. Чому вищезазначені сайти поводяться по-різному (особливо Debuggex, збігаючись один раз лише на \nта один раз \r\n)?

15
Ви можете спробувати [\r\n]+- або щось подібне
Іллю Бурсов

3
Я використовую: \r?\nдля узгодження обох \r\nі \nпослідовностей завершення рядків. Він не працює для старого \rсинтаксису Mac, але цей сьогодні є досить рідкісним.
егергернер

6
Гей, я засновник налагодження. Це схоже на помилку (для налагодження я не можу говорити за інших). Я додав найвищу проблему із посиланням на це питання. Ми досягнемо цього якнайшвидше - зараз ми зосереджуємо всі наші (дуже обмежені) ресурси на запуску іншого продукту.
Sergiu Toarca

2
@ridgerunner, щоб додати до цього синтаксис Mac, ви могли б зробити (\ r? \ n | \ r), що схоже на відповідь Пітера ван дер Уола нижче, але більш компактне (10 символів проти 12 символів).
Doktor J

Відповіді:


220

Зробимо відповідь у зворотному напрямку.

2) Для повного пояснення \rі \nмені потрібно звернутися до цього питання, яке набагато повніше, ніж я буду публікувати тут: Різниця між \ n та \ r?

Коротше кажучи, Linux використовує \nдля нової лінії, Windows \r\nта старих Macs \r. Тож існує кілька способів написання нового рядка. Ваш другий інструмент (RegExr), наприклад, відповідає сінглу \r.

1) [\r\n]+як запропонував Ілля, буде працювати, але також відповідатиме декільком поспіль новим рядкам. (\r\n|\r|\n)правильніше.


Отже, \r/ \nзалежать від операційної системи - це річ, про яку можна знати (;)) - але чому два приклади налагодження збігаються один раз на \ r \ n та один раз на \ n? Принаймні, різниці (у прикладах) для мене не видно.
KeyNone

Швидше за все, тому що ви скопіювали один із текстового редактора Windows, а другий, який ви написали, прямо в текстову область налагодження. Кожен використовував різні розриви рядків.
OGHaza

1
Дійсно, тому що у вашому третьому прикладі (Старші чоловіки ...) є \r\nтекст у тексті (якщо клацнути правою кнопкою миші та показати джерело, ви знайдете {{Infobox XC Championships\r\n|Name =десь). Другий інструмент написаний у Flash, і коли ви читаєте сторінку приблизно трохи баггі з новими символами.
Пітер ван дер Валь

1
(\r\n|\r|\n)можна записати простіше як\r\n?
Асад Саєдюддін

2
@AsadSaeeduddin Ні, це не може. Це не збігатиметься з лінійкою фіналу Unix\n
Пітер ван дер Валь

12

У прикладних текстах на Debuggex у вас різні закінчення рядків. Особливо цікаво те, що Debuggex, схоже, визначив, який стиль закінчення рядка ви використовували спочатку, і він перетворює всі додаткові закінчення рядків, введені до цього стилю.

Я використовував Notepad ++, щоб вставити зразок тексту у форматі Unix та Windows у Debuggex, і що б я вставив першим - це те, на чому дотримувався сеанс Debuggex.

Отже, ви повинні помити текст через текстовий редактор, перш ніж вставляти його в Debuggex. Переконайтеся, що ви вставляєте потрібний стиль. Налагодження за замовчуванням до стилю Unix (\ n).

Також NEL (\ u0085) є цілком іншим: https://en.wikipedia.org/wiki/Newline#Unicode

(\r?\n)буде охоплювати Unix та Windows. Вам знадобиться щось складніше, наприклад (\r\n|\r|\n), якщо ви теж хочете відповідати старому Mac.


Дуже цікавий момент про налагодження! Також, дякую, що вказали на \ u0085, потрапили в оману!
KeyNone


2

Це стосується лише питання 1.

У мене є додаток, яке працює в Windows і використовує багаторядковий редактор MFC.
У вікні редактора очікуються розриви рядків CRLF, але мені потрібно проаналізувати текст, введений за
допомогою деяких дійсно великих / неприємних регулярних виразів '.

Я не хотів наголошувати на цьому під час написання регулярних виразів, тому
я закінчився нормалізацією між парсером та редактором, щоб
просто використовували регулярні виразки \n. Я також захоплюю операції пасти і конвертую їх для скриньки.

Це не займе багато часу.
Це те, що я використовую.

 boost::regex  CRLFCRtoLF (
     " \\r\\n | \\r(?!\\n) "
     , MODx);

 boost::regex  CRLFCRtoCRLF (
     " \\r\\n?+ | \\n "
     , MODx);


 // Convert (All style) linebreaks to linefeeds 
 // ---------------------------------------
 void ReplaceCRLFCRtoLF( string& strSrc, string& strDest )
 {
    strDest  = boost::regex_replace ( strSrc, CRLFCRtoLF, "\\n" );
 }

 // Convert linefeeds to linebreaks (Windows) 
 // ---------------------------------------
 void ReplaceCRLFCRtoCRLF( string& strSrc, string& strDest )
 {
    strDest  = boost::regex_replace ( strSrc, CRLFCRtoCRLF, "\\r\\n" );
 }

2

На Python:

# as Peter van der Wal's answer
re.split(r'\r\n|\r|\n', text, flags=re.M) 

або більш жорсткі:

# https://docs.python.org/3/library/stdtypes.html#str.splitlines
str.splitlines()
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.