JS регулярний вираз для поділу на рядок


78

Як розділити довгий фрагмент тексту на окремі рядки? Чому цей зворотний рядок1 двічі?

/^(.*?)$/mg.exec('line1\r\nline2\r\n');

["рядок1", "рядок1"]

Я увімкнув багаторядковий модифікатор, щоб створити ^та $зрівняти початок і кінець рядків. Я також увімкнув глобальний модифікатор для захоплення всіх рядків.

Я хотів би використовувати спліт регулярного виразу, а не String.splitтому, що я буду мати справу як із закінченнями рядків Linux, так \nі Windows \r\n.

Відповіді:


146
arrayOfLines = lineString.match(/[^\r\n]+/g);

Як сказав Тім, це і весь матч, і захоплення. Здається, regex.exec(string)повертається при пошуку першого збігу незалежно від глобального модифікатора, коли ж шана string.match(regex)глобальна.


9
Як зауважимо, Тім збігатиметься з порожніми рядками, а у мене - ні. Або може бути, або не бажано.
ReactiveRaven

Стара відповідь, але я хотів би сказати, що причина execповертається при першому збігу, тому що він призначений для виклику кілька разів для глобальних регулярних виразів, поки не поверне нуль, і регулярний вираз зберігає такі речі, як lastIndexіндекс, з якого починається наступний матч.
iPherian

Спробуйте "123\n\n1234".match(/[^\r\n]+/g);очікувано Array [ "123", "", "1234" ], але отрималиArray [ "123", "1234" ]
морський кг

105

Використовуйте

result = subject.split(/\r?\n/);

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


4
Вам потрібно використовувати gпрапор і \rє дійсним новим рядком на деяких старих машинах Apple. Крім того, Unicode визначає \u2028, \u2029та старий рядок IBM \u0085як нові рядки. Так /[\n\u0085\u2028\u2029]|\r\n?/gобробляє всі кромкові кейси.
Mike Samuel

7
@Mike: Ви впевнені у /gпрапорі? Немає сенсу мати функцію розділення, яка розділяється лише один раз, якщо явно не вказано інше. І Джоджо сказав, що має справу лише з Linux та Windows. Що далі, EBCDIC?
Тім Пітцкер,

4
@Mike: Ні, /gпрапор не потрібен. Ви можете додати його, але JavaScript просто ігнорує. Як сказав Тім, поведінка за замовчуванням полягає в тому, щоб розділити якомога більше разів, але ви можете використовувати другий аргумент, щоб накласти максимум.
Алан Мур,

23
Що стосується того, що становить новий рядок, це навіть гірше, ніж це. Згідно з консорціумом Unicode, ми повинні завжди користуватися (\r\n|[\n\v\f\r\x85\u2028\u2029])незалежно від того, на якій платформі працює програмне забезпечення або звідки беруться дані.
Алан Мур,

@ Алан, цілком правильно. У gконтролює прапор будьте захоплюючими групи, включені в вихідних даних .
Mike Samuel

26

Я припускаю, що наступні складають нові рядки

  1. \ r, а потім \ n
  2. \ n, а потім \ r
  3. \ n присутній поодинці
  4. присутні поодинці

Будь ласка, використовуйте

var re=/\r\n|\n\r|\n|\r/g;

arrayofLines=lineString.replace(re,"\n").split("\n");

для масиву всіх рядків, включаючи порожні.

АБО

Будь ласка, використовуйте

arrayOfLines = lineString.match(/[^\r\n]+/g); 

Для масиву не пустих рядків


\nза нею \rнемає жодного нового рядка
JLRishe

22

Ще простіший регулярний вираз, який обробляє всі комбінації закінчень рядків, навіть змішаних в одному файлі, а також видаляє порожні рядки:

var lines = text.split(/[\r\n]+/g);

З обрізкою пробілів:

var lines = text.trim().split(/\s*[\r\n]+\s*/g);


1
Перший видаляє порожні рядки в середині тексту, але не на початку або в кінці. Це добре для моїх цілей, я просто вказую на це всім, хто потребує видалення, щоб бути послідовним.
twm

6

Спочатку замініть все \r\nна \n, потім String.split .


Для цього потрібно дві команди. Чи можна це зробити за допомогою регулярного виразу в одній команді?
JoJo

2
@JoJo: myString.replace(/\r\n/, "\n").split("\n")(якщо ви не запитуєте через академічний інтерес :))
Тім,

'line1\r\nline2\r\n'.replace(/\r\n/, '\n').split('\n').without('');виробляє неправильну другу клітинку:["line1", "line2\r"]
JoJo

@JoJo: Вибачте, я забув /gпрапор для глобального! Це повинно бути:myString.replace(/\r\n/g, "\n").split("\n")
Тім,

3
@Jojo: Це стисло в одному рядку :) Регекси не є інструментом для кожної роботи. Вони можуть бути дуже потужними, але не повинні використовуватися скрізь. Зверніть увагу, що replace це регулярний вираз.
Тім

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.