Удалить все точки, кроме первой, из строки - PullRequest
16 голосов
/ 15 ноября 2011

С учетом строки

'1.2.3.4.5'

Я хотел бы получить этот вывод

'1.2345'

(Если в строке нет точек, строка должна быть возвращена без изменений.)

Я написал это

function process( input ) {
    var index = input.indexOf( '.' );

    if ( index > -1 ) {
        input = input.substr( 0, index + 1 ) + 
                input.slice( index ).replace( /\./g, '' );
    }

    return input;
}

Демонстрационная версия: http://jsfiddle.net/EDTNK/1/

Это работает, но я надеялся на более элегантное решение ...

Ответы [ 11 ]

17 голосов
/ 15 ноября 2011

Существует довольно короткое решение (при условии, что input - ваша строка):

var output = input.split('.');
output = output.shift() + '.' + output.join('');

Если input равно "1.2.3.4", то output будет равно "1.234".

См. этот jsfiddle для доказательства. Конечно, вы можете включить его в функцию, если сочтете это необходимым.

EDIT:

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

var output = input.split('.');
output = output.shift() + (output.length ? '.' + output.join('') : '');

который уйдет например. «1234» (точка не найдена) без изменений. См. этот jsfiddle для обновленного кода.

10 голосов
/ 15 ноября 2011

С reg exp было бы намного проще, если бы поддерживаемые браузеры смотрели сзади.

В одну сторону с регулярным выражением:

function process( str ) {
    return str.replace( /^([^.]*\.)(.*)$/, function ( a, b, c ) { 
        return b + c.replace( /\./g, '' );
    });
}
2 голосов
/ 15 ноября 2011

Вы можете попробовать что-то вроде этого:

str = str.replace(/\./,"#").replace(/\./g,"").replace(/#/,".");

Но вы должны быть уверены, что символ # не используется в строке;или замените его соответствующим образом.

Или это без вышеуказанного ограничения:

str = str.replace(/^(.*?\.)(.*)$/, function($0, $1, $2) {
  return $1 + $2.replace(/\./g,"");
});
1 голос
/ 15 ноября 2011

Вот еще один подход:

function process(input) {
    var n = 0;
    return input.replace(/\./g, function() { return n++ > 0 ? '' : '.'; });
}

Но можно сказать, что это основано на побочных эффектах и ​​поэтому не очень элегантно.

1 голос
/ 15 ноября 2011

Это не обязательно более элегантно, но это еще один способ снять кожу с кошки:

var process = function (input) {
    var output = input;

    if (typeof input === 'string' && input !== '') {
        input = input.split('.');
        if (input.length > 1) {
            output = [input.shift(), input.join('')].join('.');
        }
    }

    return output;
};
1 голос
/ 15 ноября 2011

Вы также можете сделать что-то вроде этого, я также не знаю, если это "проще", но он использует только indexOf, replace и substr.

var str = "7.8.9.2.3";
var strBak = str;

var firstDot = str.indexOf(".");
str = str.replace(/\./g,"");
str = str.substr(0,firstDot)+"."+str.substr(1,str.length-1);

document.write(str);

Шай.

0 голосов
/ 06 июля 2017

Основано на ответе @ Tadek выше. Эта функция учитывает другие локали.


Например, некоторые локали будут использовать запятую для десятичного разделителя и точку для разделителя тысяч (например, -451.161,432e-12).

Сначала мы конвертируем все, кроме 1) чисел; 2) отрицательный знак; 3) показатель экспоненты в период ("-451.161.432e-12").

Далее мы разбиваемся по периоду (["-451", "161", "432e-12"]) и выскакиваем крайнее правое значение ("432e-12"), затем соединяем с остальными ("-451161.432e-12")

(Обратите внимание, что я выбрасываю тысячи разделителей, но их можно легко добавить на этапе объединения (.join(','))

var ensureDecimalSeparatorIsPeriod = function (value) {
    var numericString = value.toString();
    var splitByDecimal = numericString.replace(/[^\d.e-]/g, '.').split('.');
    if (splitByDecimal.length < 2) {
        return numericString;
    }
    var rightOfDecimalPlace = splitByDecimal.pop();
    return splitByDecimal.join('') + '.' + rightOfDecimalPlace;
};
0 голосов
/ 31 июля 2015
var input = '14.1.2';
reversed = input.split("").reverse().join("");
reversed = reversed.replace(\.(?=.*\.), '' );
input = reversed.split("").reverse().join("");
0 голосов
/ 27 ноября 2013

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

JavaScript

var match = string.match(/^[^.]*\.|[^.]+/g);
string = match ? match.join('') : string;

Требуется вторая строка кода, потому что если match() вернет null , мы получим исключение при попытке вызвать join() для null . (Улучшения приветствуются.)

Objective-J / Cappuccino (расширенный набор JavaScript)

string = [string.match(/^[^.]*\.|[^.]+/g) componentsJoinedByString:''] || string;

Может сделать это в одной строке, потому что его селекторы (такие как componentsJoinedByString:) просто возвращают null при отправке в null значение, а не выдают исключение.

Что касается регулярного выражения, то я сопоставляю все подстроки, состоящие из (a) начала строки + любого потенциального числа не-точечных символов + точка или (b) любое существующее количество символов без точек . Когда мы объединяем все матчи вместе, мы по существу удаляем любую точку, кроме первой.

0 голосов
/ 15 ноября 2011
var i = s.indexOf(".");
var result = s.substr(0, i+1) + s.substr(i+1).replace(/\./g, "");

Довольно сложно. Работает, используя тот факт, что indexOf возвращает -1, если элемент не найден.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...