709

How can I read the line break from a value with JavaScript and replace all the line breaks with <br /> elements?

Example:

A variable passed from PHP as below:

  "This is man.

     Man like dog.
     Man like to drink.

     Man is the king."

I would like my result to look something like this after the JavaScript converts it:

  "This is man<br /><br />Man like dog.<br />Man like to drink.<br /><br />Man is the king."
John
  • 1
  • 13
  • 98
  • 177
Jin Yong
  • 42,698
  • 72
  • 141
  • 187
  • 1
    Something wrong with your original question? http://stackoverflow.com/questions/784313/read-line-break-in-a-string-with-javascript – harto Apr 24 '09 at 04:42
  • 1
    You could also do nl2br($string) in PHP before you send it to JavaScript. – alex Apr 24 '09 at 04:44
  • 1
    I'm going to vote to close the earlier question, as this has a better example. – eyelidlessness Apr 24 '09 at 04:48
  • 2
    He should edit the initial question then – nickf Apr 24 '09 at 04:48
  • I came here from a misguided understanding to what was going on with .text(). See https://stackoverflow.com/q/35238362/1467396 if that's what you're doing, too – David Aug 14 '19 at 21:54

14 Answers14

1500

This will turn all returns into HTML

str = str.replace(/(?:\r\n|\r|\n)/g, '<br>');

In case you wonder what ?: means. It is called a non-capturing group. It means that group of regex within the parentheses won't be saved in memory to be referenced later. You can check out these threads for more information:
https://stackoverflow.com/a/11530881/5042169 https://stackoverflow.com/a/36524555/5042169

Jun
  • 2,942
  • 5
  • 28
  • 50
eyelidlessness
  • 62,413
  • 11
  • 90
  • 94
  • 96
    Just additional note: `str.replace("\n", '
    ')` (first argument is a regular string) will replace only first occurrence.
    – Serge S. Apr 15 '13 at 20:49
  • 23
    Another version (to replace multiple line-breaks): str.replace(/(\n)+/g, '
    ');
    – Ritesh Apr 16 '13 at 16:30
  • 6
    @SergeS. Thanks for that extra comment. Just saved me a TONNE of time! [jsfiddle](http://jsfiddle.net/yPSEZ/7/) – EleventyOne Aug 11 '13 at 03:37
  • @EleventyOne thanks for the jsfiddle, makes life much simpler for me! – Kirk Broadhurst Sep 01 '13 at 02:48
  • 5
    @SergeS., `String#replace` coerces its first argument from `String` to an escaped `RegExp` instance, with no flags. `str.replace('\n', '
    ');` is equivalent to `str.replace(new RegExp('\n'), '
    ');`
    – eyelidlessness Jan 19 '14 at 07:37
  • @eyelidlessness, Thanks for explanation! Yep, this is the reason. Intuitively it's easy to assume that `String#replace` expects first argument to be a regular string, and it will replace all occurrences by default. That's why many mistakes are made with replacing strings in JS ;) – Serge S. Jan 22 '14 at 10:15
  • @eyelidlessness - Would you consider updating your answer to use the expression `('\r?\n','g')`, since some systems use `\r`? – David Bradbury May 19 '14 at 15:39
  • 1
    @Conexion, `\r?\n` is not correct either. Some other systems use `\r` alone. I'll update for all cases. – eyelidlessness May 19 '14 at 19:59
  • 4
    Here is a test case compare to `str.split("\n").join("
    ")` http://jsperf.com/split-join-vs-replace-regex RegEx seems slightly faster
    – Aley Jan 30 '15 at 19:31
  • 1
    \r?\n|\r is slightly shorter than \r\n|\r|\n – Mike Sep 29 '16 at 11:17
  • There is no slash needed in break tag these days. – ar2015 Jul 25 '17 at 00:22
  • Not sure this solution OK. consider this string "a \\n b \n c" which we want to be: "a \n b
    c", but: we will get: "a \
    b
    c"
    – Dudi Sep 13 '17 at 14:37
  • 1
    I stumble upon this character in my json response: `↵` This is basically `u21B5` [link](https://graphemica.com/%E2%86%B5). @eyelidlessness solution does also work in this case. – John Archer May 14 '19 at 10:50
  • Why do `/(?:\r\n|\r|\n)/g` instead of just `/\r\n|\r|\n/g`? It seems like it does exactly the same thing. What's the advantage of the non-capturing group? – Clonkex Jun 21 '19 at 04:56
  • 2
    @Clonkex using `?:` will match whatever is in the group, but not return it, while the rest of the expression that matched will return, which is useful in some cases, but I actually don't see a difference in using it here, as nothing gets returned—just replaced ¯\_(ツ)_/¯ – Ludolfyn May 03 '20 at 13:36
  • Is adding the non-capturing group worth the improvement in performance for the degrease in readability? – Elijah Mock Aug 02 '23 at 21:08
565

If your concern is just displaying linebreaks, you could do this with CSS.

<div style="white-space: pre-line">Some test
with linebreaks</div>

Jsfiddle: https://jsfiddle.net/5bvtL6do/2/

Note: Pay attention to code formatting and indenting, since white-space: pre-line will display all newlines (except for the last newline after the text, see fiddle).

bersling
  • 17,851
  • 9
  • 60
  • 74
  • 19
    I came here looking for the regex and left with this. In lots of occasions this is what people are looking for. We use linebreaks for emails and need to display what the email looked line in html, sometimes. Perfecto. Thanks for looking at the question in a different light – O'Mutt Mar 01 '16 at 19:01
  • 1
    This might work for actual line breaks, but what if I have "\n"s like in the question? Can I solve this by CSS, too? – Froxx May 24 '16 at 10:13
  • 30
    Instead of `white-space: pre-wrap;` I prefer use `white-space: pre-line;` (to not add a final break line after all) – jpmottin Aug 09 '16 at 17:54
  • 5
    looks good but what about a giant space before the first line? weird – Toolkit Feb 04 '17 at 11:12
  • @Toolkit good point, you can omit this space by not adding a line break after the opening div tag or with the infamous trick. – bersling Feb 20 '17 at 09:10
  • Amazing. I couldn't even get the JS approach to work. This works! – Miek Mar 10 '17 at 19:34
  • Unfortunately not supported by IE11 and Edge. https://caniuse.com/#search=white-space – Mark Hewitt Apr 04 '18 at 04:05
  • 1
    @MarkHewitt It does work in IE11 and Edge. I don't know why caniuse states otherwise, but I just tested in IE11 and also https://www.w3schools.com/cssref/pr_text_white-space.asp states that it works and also https://developer.mozilla.org/en-US/docs/Web/CSS/white-space. – bersling Apr 04 '18 at 10:38
  • @bersling You're right, it does work. I loaded up the Mozilla page on IE 11 and Edge 16, both on Windows 10, and they work just fine. I wonder if the caniuse data relates to the following? "Method of customizing the width of the tab character. Only effective using 'white-space: pre' or 'white-space: pre-wrap'." In the uncertainty, I'm glad I went with paulslater19's solution https://stackoverflow.com/a/8412950/600960 – Mark Hewitt Apr 06 '18 at 01:29
  • 1
    Excellent. I did not even think to ask about a CSS solution. Thank you very much. – Jared Becksfort Oct 18 '18 at 15:20
  • the regex did not work for me ! but this did ! thank youuuuu – Az Emna Feb 18 '19 at 13:04
  • 4
    @jpmottin I think your version is closer to what the question author was looking for, so I changed my answer to `white-space: pre-line` as well. Thank you! – bersling Apr 12 '20 at 07:22
  • @Toolkit you can use JS `.trim()` function to remove white space before and after. Or you can use `.trimStart() / .trimLeft()` to remove white space at the start. – Kalimah Apr 14 '20 at 10:02
  • All of the methods above this answer converted \n to
    just fine but none rendered the break. They all got URI encoded when actually displayed in the text. But, the simple CSS rule in this answer worked perfect! Needs more upvotes!!
    – dbonneville Feb 22 '21 at 19:16
89

Without regex:

str = str.split("\n").join("<br />");
paulslater19
  • 5,869
  • 1
  • 28
  • 25
47

This works for input coming from a textarea

str.replace(new RegExp('\r?\n','g'), '<br />');
WSkinner
  • 2,147
  • 1
  • 19
  • 21
  • 1
    It's the best answer for me because you didn't forget the \r, which is used on some systems – Liglo App Jan 17 '14 at 14:47
  • 1
    This is the best answer for this question. But I will just go with
    not
    . See this one http://stackoverflow.com/questions/1946426/html-5-is-it-br-br-or-br
    – kheya Mar 12 '14 at 19:26
13

If the accepted answer isn't working right for you then you might try.

str.replace(new RegExp('\n','g'), '<br />')

It worked for me.

Jethro Larson
  • 2,337
  • 1
  • 24
  • 24
11

Shortest code supporting the most common EOL styles \r, \n, \r\n and using HTML5 <br>:

s.replace(/\r?\n|\r/g, '<br>')
Afanasii Kurakin
  • 3,330
  • 2
  • 24
  • 26
8

Regardless of the system:

my_multiline_text.replace(/$/mg,'<br>');
  • 1
    Caution: This will append a '
    ' tag to any string, regardless if there's a ‘\n‘ in it.
    – mkoeller Oct 29 '19 at 15:53
  • You could fix the error @mkoeller mentioned by adding this after the first replacement: `.replace(/\
    $, '')`, which will remove that last `
    ` ("search for `
    ` that touches the end of the string (`$`), and replace it with an empty string (`''`)")
    – Samathingamajig Jul 17 '21 at 21:02
7

It is also important to encode the rest of the text in order to protect from possible script injection attacks

function insertTextWithLineBreaks(text, targetElement) {
    var textWithNormalizedLineBreaks = text.replace('\r\n', '\n');
    var textParts = textWithNormalizedLineBreaks.split('\n');

    for (var i = 0; i < textParts.length; i++) {
        targetElement.appendChild(document.createTextNode(textParts[i]));
        if (i < textParts.length - 1) {
            targetElement.appendChild(document.createElement('br'));
        }
    }
}
Dmitry Dzygin
  • 1,258
  • 13
  • 26
6

This worked for me when value came from a TextBox:

string.replace(/\n|\r\n|\r/g, '<br/>');
Dr. Aaron Dishno
  • 1,859
  • 1
  • 29
  • 24
3

For those of you who just want to allow max. 2 <br> in a row, you can use this:

let text = text.replace(/(\r?\n){2,}/g, '<br><br>');
text = text.replace(/(\r?\n)/g, '<br>');

First line: Search for \n OR \r\n where at least 2 of them are in a row, e.g. \n\n\n\n. Then replace it with 2 br

Second line: Search for all single \r\n or \n and replace them with <br>

maxeh
  • 1,373
  • 1
  • 15
  • 24
2

if you send the variable from PHP, you can obtain it with this before sending:

$string=nl2br($string);
Luca C.
  • 11,714
  • 1
  • 86
  • 77
0

It will replace all new line with break

str = str.replace(/\n/g, '<br>')

If you want to replace all new line with single break line

str = str.replace(/\n*\n/g, '<br>')

Read more about Regex : https://dl.icewarp.com/online_help/203030104.htm this will help you everytime.

Ritu Gupta
  • 2,249
  • 1
  • 18
  • 11
0

Not answering the specific question, but I am sure this will help someone...

If you have output from PHP that you want to render on a web page using JavaScript (perhaps the result of an Ajax request), and you just want to retain white space and line breaks, consider just enclosing the text inside a <pre></pre> block:

var text_with_line_breaks = retrieve_some_text_from_php();
var element = document.querySelectorAll('#output');
element.innerHTML = '<pre>' + text_with_line_breaks + '</pre>';
osullic
  • 543
  • 1
  • 8
  • 21
-1

I had a config in PHP that was being passed in from the Controller. (Laravel)

Example: PHP Config

'TEXT_MESSAGE' => 'From:Us\nUser: Call (1800) 999-9999\nuserID: %s'

Then in javascript using es6 reduce. notice I had to have two \\ or the output was not being replace correctly. Here are the parameters that are assoicated with the reduce function

  • previousValue (the value resulting from the previous call to callbackfn)
  • currentValue (the value of the current element)
  • currentIndex Optional
  • array (the array to traverse) Optional
//p is previousVal
//c is currentVal
String.prototype.newLineReplace = function(){
    return [...arguments].reduce((p,c) => p.replace(/\\n/g,c), this);
}

Here is how i used it in my script.

<script type="text/javascript">var config = @json($config);</script>

config.TEXT_MESSAGE.newLineReplace("<br />")

of course you could just called it on a javascript sring like...

let a = 'From:Us\nUser: Call (1800) 999-9999\nuserID: %s'
var newA = a.newLineReplace("<br />")

//output
'From:Us<br />User: Call (1800) 999-9999<br />userID: %s'
Quickee
  • 321
  • 1
  • 6
  • 13