2013-12-19 4 views
4

Я хотел бы разбить строку на %\d+ или \n. Я был в состоянии успешно разделить на любом из этих двух, но не на обоих:Почему результаты string.split() не определены?

> msg = 'foo %1 bar \n baz %2' 

> msg.split(/(%\d+)/) 
["foo ", "%1", " bar 
baz ", "%2", ""] 

> msg.split(/(\n)/) 
["foo %1 bar ", " 
", " baz %2"] 

> msg.split(/(\n)|(%\d)/) 
["foo ", undefined, "%1", " bar ", " 
", undefined, " baz ", undefined, "%2", ""] 

В последнем случае, почему в результирующем массиве undefined, и что я должен делать?

Обновление: Я забыл указать, что мне нужны разделители. В результате я хочу это:

["foo ", "%1", " bar ", "\n", " baz ", "%2"] 
+2

Захват групп, которые не фиксировали никакого значения, дают 'undefined' – Bergi

ответ

6

Цитируя MDN doc для String.prototype.split:

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

Дело в том, что любой захвата группы сращивания - даже тот, который не попадает в створ. Первый undefined в вашем примере - это «ничто», совпадающее с \n (сделка произошла, когда %\d соответствует), вторая для %\d (когда был сопоставлен \n) ... вы видите изображение.

Чтобы решить эту проблему, вы можете избавиться от захвата групп (как оператор Чередование имеет самый низкий приоритет в любом случае):

msg.split(/\n|%\d/); // ["foo ", " bar ", " baz ", ""] 

Если вам нужно, что разделяющие части, а также, использовать только одну захвата группы:

msg.split(/(\n|%\d)/); 
// ["foo ", "%1", " bar ", "\n", " baz ", "%2", ""] 
+0

Спасибо. Я забыл заявить, что мне нужны предметы, на которых я раскололся. Я уточню свой вопрос. –

+0

@espertus Обновлен мой ответ. – raina77ow

+0

Спасибо. Я не понимал приоритета достаточно хорошо, чтобы знать, чтобы опустить круглые скобки вокруг дизъюнктов. –

Смежные вопросы