Разделить строку в JavaScript, используя регулярное выражение с просмотром назад нулевой ширины

Я знаю, что регулярные выражения JavaScript имеют встроенную функцию просмотра вперед, но не функцию просмотра назад.

Я хочу разбить строку в точках, начинающихся с любого члена одного набора символов или заканчивающихся любым членом другого набора символов.

Разделить перед , , , , . Разделить после .

In: ເລື້ອຍໆມະຫັດສະຈັນເອກອັກຄະລັດຖະທູດ

Out: ເລື້ອຍໆມະ ຫັດສະ ຈັນ ເອກອັກຄະ ລັດຖະ ທູດ

Я могу выполнить часть «разделить до», используя просмотр с нулевой шириной:

'ເລື້ອຍໆມະຫັດສະຈັນເອກອັກຄະລັດຖະທູດ'.split(/(?=[ໃໄໂເແ])/)

["ເລື້ອຍໆມະຫັດສະຈັນ", "ເອກອັກຄະລັດຖະທູດ"]

Но я не могу придумать общий подход к моделированию просмотра назад с нулевой шириной

Я разбиваю строки произвольного текста Unicode, поэтому не хочу заменять специальные маркеры в первом проходе, так как я не могу гарантировать отсутствие какой-либо строки из моего ввода.


person hippietrail    schedule 29.08.2014    source источник


Ответы (3)



Вы можете попробовать сопоставить, а не разделить,

> var re = /((?:(?!ະ).)+(?:ະ|$))/g;
undefined
> var str = "ເລື້ອຍໆມະຫັດສະຈັນເອກອັກຄະລັດຖະທູດ"
undefined
> var m;
undefined
> while ((m = re.exec(str)) != null) {
... console.log(m[1]);
... }
ເລື້ອຍໆມະ
ຫັດສະ
ຈັນເອກອັກຄະ
ລັດຖະ
ທູດ

Затем снова разделите элементы массива с помощью просмотра вперед.

person Avinash Raj    schedule 29.08.2014
comment
RegExp.prototype.exec непоследовательно реализуется в некоторых браузерах в Интернете, String.prototype.match обычно предпочтительнее - person axelduch; 29.08.2014
comment
@hwnd могу ли я узнать, в каких случаях приведенное выше регулярное выражение не удастся. - person Avinash Raj; 29.08.2014

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

"ເລື້ອຍໆມະຫັດສະຈັນເອກອັກຄະລັດຖະທູ".split(/(ະ)/).reduce(function(arr,str,index) {
   if (index%2 == 0) { 
     arr.push(str); 
   } else { 
     arr[arr.length-1] += str
   }; 
   return arr;
 },[])

Результат: ["ເລື້ອຍໆມະ", "ຫັດສະ", "ຈັນເອກອັກຄະ", "ລັດຖະ", "ທູ"]

Вы можете сделать еще один проход, чтобы разделить просмотр вперед:

"ເລື້ອຍໆມະຫັດສະຈັນເອກອັກຄະລັດຖະທູ".split(/(ະ)/).reduce(function(arr,str,index) {
   if (index%2 == 0) { 
     arr.push(str); 
   } else { 
     arr[arr.length-1] += str
   }; 
   return arr;
 },[]).reduce(function(arr,str){return arr.concat(str.split(/(?=[ໃໄໂເແ])/));},[]);

Результат: ["ເລື້ອຍໆມະ", "ຫັດສະ", "ຈັນ", "ເອກອັກຄະ", "ລັດຖະ", "ທູ"]

person Mark Reed    schedule 29.08.2014
comment
В первом проходе, прежде чем делать проход в части просмотра вперед? Это то, с чем я играю прямо сейчас (-: ... - person hippietrail; 29.08.2014
comment
Есть один способ, которым это решение не является общим. Если конечный шаблон может быть разным количеством символов. Этого не происходит в моей текущей итерации, но может произойти в будущем, и более общие решения лучше (-: ... Затем я снова указал характер в своем вопросе. - person hippietrail; 29.08.2014
comment
Я не понимаю, какое это имеет значение. Шаблон разделения может так же легко быть чередованием ... каким бы ни был фактический разделитель в каждом случае, он все равно будет включен и добавлен к предыдущей строке. - person Mark Reed; 29.08.2014
comment
Ты прав. Я думал, что увидел что-то жестко закодированное на длине ະ, но нет. - person hippietrail; 29.08.2014