Можно ли группировать числа (например, преобразовать число 1000
в строку "1 000"
), используя один проход с только регулярными выражениями ? (Я знаю, что границы между regexp и языковыми возможностями в некоторых системах немного размыты - прислушайтесь к своей совести, прежде чем отвечать.)
Причина, по которой я спрашиваю: недавно другой разработчик спросил меня, как сделать группировку чисел в JavaScript, и показал мне немного некорректную функцию JavaScript с использованием регулярных выражений. Я дал ему лучшую альтернативу , но его регулярное выражение не давало мне покоя, потому что этот вид переписывания определенно то, что должна делать обычная грамматика, но я действительно не могу понять, как написать регулярное выражение для Это.
Это моя первая наивная попытка, которая, как я знал, будет неверной:
function group(n) { return n.toString().replace(/(\d{3})/g, "$1 "); }
У этого подхода есть два недостатка; group(1000)
дает "100 0"
, а group(100)
дает "100 "
(завершающий пробел). Вы можете исправить это так:
String.prototype.reverse = function () {
var a = [];
for (var i = this.length; i >= 0; --i) a.push(this[i]);
return a.join("");
};
function group(n) {
return n.toString().reverse().replace(/(\d{3})/g, "$1 ").
trimRight().reverse();
}
Но для этого требуется не один, не два, даже не три, а ЧЕТЫРЕ прохода (два реверса, один заменитель и trimRight
)! Затем я отважился выйти на землю, где можно было наблюдать, и придумал:
function group(n) { return n.toString().replace(/(\d{3}(?!\d))/g, " $1");
... который вообще не работает ( редактировать - возможно, потому что я перепутал просмотр назад и отрицательный просмотр вперед ... ) - он соответствует только трем последним цифрам (group(1000000000)
становится "1000000 000"
). Предварительный просмотр работает немного лучше:
function group(n) { return n.toString().replace(/(\d{3})(?=\d)/g, "$1 "); }
Что более или менее возвращает меня туда, откуда я начал - я избавился от конечного пробела, но group(1000)
все еще дает "100 0"
.
Итак, можно ли это сделать с помощью одного прохода замены регулярного выражения? Я не зависим от языка, так как для этого нужно использовать только регулярные выражения.
Примечание: это не вопрос о том, как сделать локализацию, и я не участвую в преждевременной оптимизации. Мне просто любопытно, возможно ли это, а если нет, то почему бы и нет.