使用JavaScript从后面每3个字符拆分字符串

11

如何使用JavaScript将字符串从后面每3个字符分割一次?

比如,我有这样一个字符串:

str = 9139328238

经过所需的功能后,它将变成:

parts = ['9','139','328','238']

我们如何优雅地实现这个?


看起来你正在尝试显示带小数点的数字。如果是这样,最好使用 Number.prototype.toLocaleString() 本地方法。 - Yves M.
9个回答

21
var myString = String( 9139328238 );
console.log( myString.split( /(?=(?:...)*$)/ ) );
// ["9", "139", "328", "238"]

我无法做出任何性能保证。对于较小的字符串,它应该是可以胜任的。

以下是一个循环实现:

function funkyStringSplit( s )
{
    var i = s.length % 3;
    var parts = i ? [ s.substr( 0, i ) ] : [];
    for( ; i < s.length ; i += 3 )
    {
        parts.push( s.substr( i, 3 ) );
    }
    return parts;
}

8
为了生成所需的输出,您应该使用非捕获组:/(?=(?:...)*$)/ - Felix Kling
捕获与否对于拆分而言有何影响?它是在拆分,而非使用捕获。 - Alex
2
我在控制台中使用了一个不同的字符串...让我编辑一下... --- 结果发现我并没有。谢谢Felix! - Alex
你在数组的开头和结尾没有得到空字符串吗? - Tim Pietzcker
是的,因为正则表达式在一个3(或6或9...)个字符的字符串中分割第一个字符之前。 - Tim Pietzcker
显示剩余5条评论

4
这里有很多复杂的答案。

function group(value) {
  return value.match(/\d{1,3}(?=(\d{3})*$)/g);
}

console.log(group('1'));
console.log(group('123'));
console.log(group('1234'));
console.log(group('12345'));
console.log(group('123456'));
console.log(group('1234567'));
console.log(group('12345678'));
console.log(group('123456789'));


4
我知道这是一个老问题,但我想提供自己的一行版本来解决这个问题 :)
"12345678".split('').reverse().join('').match(/.{1,3}/g).map(function(x){
    return x.split('').reverse().join('')
}).reverse()

这基本上是将字符串反转,捕获3个元素的组,反转每个组,然后反转整个字符串。

步骤如下:

"12345678" -> [1, 2, 3, 4, 5, 6, 7, 8] //.split('')
[1, 2, 3, 4, 5, 6, 7, 8] -> [8, 7, 6, 5, 4, 3, 2, 1] //.reverse()
[8, 7, 6, 5, 4, 3, 2, 1] -> "87654321" //.join('')
"87654321" -> [876, 543, 21] //.match(...)
[876, 543, 21] -> [678, 345, 12] //.map(function(x){...})
[678, 345, 12] -> [12, 345, 678] //.reverse()

您可以使用一个字符(例如',')来连接数组,以此来分隔千位。
[12, 345, 678].join(',') -> "12,345,678"

0
const price_format = (price) => {
    let result = [];
    let new_str = [...price].reverse().join("");
    let rightSplit = new_str.match(/.{1,3}/g).reverse();
    for (let item of rightSplit) {
        result.push([...item].reverse().join(""));
    }
    return result.join(",");
}
let price = "2560000000";
console.log(price_format(price));

// output : 2,560,000,000

0

不够优雅,但可以展示 while 循环

 function commaSeparateNumber (val) {
    val = val.toString();
    while (/(\d+)(\d{3})/.test(val)){
      val = val.replace(/(\d+)(\d{3})/, '$1'+','+'$2');
    }
    return val;
  }

  var str = "9139328238";
  var splitStr = commaSeparateNumber(str).split(",");
  console.log(splitStr);

0

试试这个:

var str = 9139328238 + ''; //convert int to string
var reqArr = []; // required array
var len = str.length; //maintaining length
while (len > 0) {
    len -= 3;
    reqArr.unshift(str.slice(len)); //inserting value to required array
    str = str.slice(0, len); //updating string
}

希望它能有所帮助。

0

"12345678".split('').reverse().reduce((a, s) => (a[0].length<3?a[0]=s+a[0]:a.unshift(s),a), ['']);

“12345678” 按字符分割,反转后使用 reduce 方法,将每个字符插入到一个长度不超过 3 的数组中。最终返回一个字符串。


1
虽然答案是正确的,但我们鼓励人们提供上下文并尽可能解释所提出的解决方案。这样我们就可以一起学习和更好地理解。 - Jair Reina
1
欢迎来到SO!考虑提供支持性信息来解释你的答案。 - Ethan McTague

0

由于正则表达式操作不受每个人的喜欢,出于各种原因:这里是一个常规函数,使用一个普通循环从后面分割任何常规字符串的每X个字符。它并不花哨,但它有效:

function splitStringFromEnd(customString, every) {
  var result = [], counter = every;
  // loop that captures substring chungs of "every" length e.g.: 1000.00 -> ["000", ".00"]
  for (var i = counter; counter <= customString.length; counter += every) {
    result.unshift(customString.substr(customString.length - counter, every))
  }
  // check if there is a remainder and grabs it.
  // Using our 1000.00 example: diff = 9 - 7; remainder = 3 - 2; -> ["1", "000", ".00"]
  var diff = counter - customString.length;
  var remainder = every - diff;
  if(remainder > 0) { result.unshift(customString.substr(0, remainder)) }
  return result;
}

对于你的例子,它将是:

splitStringFromEnd("9139328238", 3);
// :returns => ["9", "139", "328", "238"]

祝您愉快 :)


-2

最后看起来不错。这是我到目前为止没有使用任何循环得到的结果。

function breakAt3(x)
    {
            if(x.length < 3){ var parts = [x]; return parts; }
        var startPos = (x.length % 3);
        var newStr = x.substr(startPos); 
        var remainingStr = x.substr(0,startPos); 

        var parts = newStr.match(/.{1,3}/g);
        if(remainingStr != ''){ var length = parts.unshift(remainingStr); }
        return parts;

    }

    var str = '92183213081';  
    var result = breakAt3(str);  // 92,183,213,081 

@Alex 加一分。他非常迅速。 - sanchitkhanna26
这个解决方案对长度小于3的字符串无效,并且对长度为3的字符串返回一个额外的空字符串。问题在于第7行的匹配可能会失败。 - Alex
1
现在长度小于3的字符串不再返回数组了!你的逻辑有问题。你正在赋值给一个新变量length,但从未使用它。 - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接