106

I have a string: "The quick brown fox jumps over the lazy dogs."

I want to use JavaScript (possibly with jQuery) to insert a character every n characters. For example I want to call:

var s = "The quick brown fox jumps over the lazy dogs.";
var new_s = UpdateString("$",5);
// new_s should equal "The q$uick $brown$ fox $jumps$ over$ the $lazy $dogs.$"

The goal is to use this function to insert &shy into long strings to allow them to wrap.

Maybe someone knows of a better way?

4
  • You're better off letting the browser wrap text. Do you have long sentences like you used for your example above, or long words? Commented Nov 20, 2009 at 20:10
  • 1
    The browser won't wrap within a word, I have long words like "ThisIsAStupidLabelThatOneOfMyUsersWillTryToMakeInMyApplication" Commented Nov 20, 2009 at 20:15
  • Wouldn't a server side solution to break words into a maximum of n characters would be better? Commented Nov 20, 2009 at 20:19
  • Possibly, but a client side solution is more easily implemented for my current predicament. Commented Nov 20, 2009 at 20:26

9 Answers 9

224

With regex

"The quick brown fox jumps over the lazy dogs.".replace(/(.{5})/g,"$1$")

The q$uick $brown$ fox $jumps$ over$ the $lazy $dogs.$
Sign up to request clarification or add additional context in comments.

9 Comments

Damn it! Nice regex-fu there. BTW is the last $ needed in the replacement string?
The last $ in the replacement string is not needed, you can put what ever you want to put at the 5 space interval here, like <br> for instance.
I arrived at "string".replace(/.{5}/g, "$&" + "<br>");. The concatenation at the end is just to make it easier to read. $& in the replacement matches the matched string, so no grouping is required.
How would that work when counting from the end of the string?
Great. One important note is if the string contains line breaks, this will start counting from zero at the start of every line, since . doesn't match \n or \r. This is perfect for folding long lines of plaintext, but may not be desirable with web content. To include newlines in the match use /[\s\S]{5}/g.
|
86
function chunk(str, n) {
    var ret = [];
    var i;
    var len;

    for(i = 0, len = str.length; i < len; i += n) {
       ret.push(str.substr(i, n))
    }

    return ret
};

chunk("The quick brown fox jumps over the lazy dogs.", 5).join('$');
// "The q$uick $brown$ fox $jumps$ over$ the $lazy $dogs."

4 Comments

@Andy E: heh, they're optional just before a closing }. I don't even realize I do that anymore. It's born from a "must conserve every byte" mentality from years before js compressors became standard ;)
String.split("") & Array.form()
regex & string.split() & array.form() & slice() & map() & JSON.parse()
A word of caution for anyone relying on this answer in 2023: substr() is a legacy function (not fully deprecated yet) and should be avoided where possible: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
64

Keep it simple

  var str = "123456789";
  var parts = str.match(/.{1,3}/g);
  var new_value = parts.join("-"); //returns 123-456-789

7 Comments

what in case I have a ten letter number and I want to have the '-' after 3rd and 6th letter only! and NOT the 9th letter.
@Learner remove the last "-" using regex.
Can you share? Thanks in advance.
"123-456-789-0".replace(/-([^-]+)$/, '$1'); //remove last dash
Love this idea. Can this be done on the fly as well (while user is still typing)?
|
8
let s = 'The quick brown fox jumps over the lazy dogs.';
s.split('').reduce((a, e, i)=> a + e + (i % 5 === 4 ? '$' : ''), '');

Explain: split('') turns a string into an array. Now we want to turn the array back to one single string. Reduce is perfect in this scenario. Array's reduce function takes 3 parameters, first is the accumulator, second is the iterated element, and the third is the index. Since the array index is 0 based, to insert after 5th, we are looking at index i%5 === 4.

1 Comment

Thank you a lot for this code. Here is the code, based on yours, I use to add a space every 2 chars for a phone number input (keyup event) : ~~~ $(this).val( $(this).val().replace(/ /g,"").split('').reduce((a,e,i) => a + e + (i % 2 === 1 ? ' ': ''),'').trim() ); ~~~
3
var str="ABCDEFGHIJKLMNOPQR";
function formatStr(str, n) {
   var a = [], start=0;
   while(start<str.length) {
      a.push(str.slice(start, start+n));
      start+=n;
   }
   console.log(a.join(" "));
}
formatStr(str,3);

1 Comment

Try to explain your answer
2
function addItemEvery (str, item, every){
  for(let i = 0; i < str.length; i++){
    if(!(i % (every + 1))){
      str = str.substring(0, i) + item + str.substring(i);
    }
   }
  return str.substring(1);
}

Result:

> addItemEvery("The quick brown fox jumps over the lazy dogs.", '$', 5)
> "The q$uick $brown$ fox $jumps$ over$ the $lazy $dogs."

Comments

2
    //first parameter: the string to be divided
    //second parameter: the character used to separate
    //third parameter: the number of characters in each division

    function separateStr(str, divider,  n)
    {
          var ret=[];

          for(let i=0; i<str.length; i=i+n) 
          {
                ret.push(str.substr(i, n))
          };

          return ret.join(divider);
    };

    separateStr('123456789', '.',  3);

    //Output: '123.456.789'

Comments

1

Here's one of the previous answers, but I wrapped it in a function, and I gave it an "offset" parameter instead of hard coding it.

// https://stackoverflow.com/a/2712896/3480193
addCharToStringEveryXSpots(str, char, offset) {
    if ( ! char ) {
        return str;
    }
    
    let regExPattern = new RegExp('(.{' + offset + '})', 'g');
    
    return str.replace(regExPattern, '$1' + char);
};

Comments

0

I did something similar to separate a friendCode for a mobile app but using Array and reduce.

This will take a string, check every n characters and add delimiter at that location.

/**
 * A function to easily inject characters every 'n' spaces
 * @param {string} friendCode The string we want to inject characters in
 * @param {*} numDigits Determines the 'n' spaces we want to inject at
 * @param {*} delimiter The character(s) we want to inject
 */
function formatFriendCode(friendCode, numDigits, delimiter) {
  return Array.from(friendCode).reduce((accum, cur, idx) => {
    return accum += (idx + 1) % numDigits === 0 ? cur + delimiter : cur;
  }, '')
}

formatFriendCode("000011112222", 4, ' ')
// output "0000 1111 2222 "

formatFriendCode("The quick brown fox jumps over the lazy dogs.", 5, '$')
// output "The q$uick $brown$ fox $jumps$ over$ the $lazy $dogs.$"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.