Pytanie Tworzenie ciągów wielowierszowych w JavaScript


Mam następujący kod w Ruby. Chcę przekonwertować ten kod na JavaScript. jaki jest równoważny kod w JS?

text = <<"HERE"
This
Is
A
Multiline
String
HERE

1924
2018-04-30 02:11


pochodzenie


Widzieć stackoverflow.com/a/6247331/632951 - Pacerier
Sprawdź to na różne sposoby, aby osiągnąć to samo. Dodałem także wydajność każdej metody stackoverflow.com/a/23867090/848841 - Vignesh Subramanian


Odpowiedzi:


Aktualizacja:

ECMAScript 6 (ES6) wprowadza nowy typ literału, mianowicie literały szablonów. Mają wiele cech, między innymi interpolację zmienną, ale najważniejsze dla tego pytania mogą być wieloliniowe.

Literał szablonu jest ograniczony przez backticks:

var html = `
  <div>
    <span>Some HTML here</span>
  </div>
`;

(Uwaga: nie zalecam używania HTML w ciągach znaków)

Obsługa przeglądarki jest OK, ale możesz użyć transpilery być bardziej kompatybilnym.


Oryginalna odpowiedź ES5:

JavaScript nie ma składni dokumentu tutaj. Możesz jednak uciec od dosłownego znaku nowej linii, która jest bliska:

"foo \
bar"

2303
2018-04-30 02:15



Ostrzegam: niektóre przeglądarki dodadzą znaki nowej linii, inne nie. - staticsan
Visual Studio 2010 wydaje się być zdezorientowany również przez tę składnię. - jcollum
dresende: To dwie linie kodu. To pojedyncze wyrażenie. - Anonymous
@Nate Jest określony w ECMA-262 5. wydanie sekcja 7.8.4 i wywołana LineContinuation : "Znak końca linii nie może pojawiać się w literale łańcuchowym, z wyjątkiem jako części znaku a LineContinuation aby stworzyć pustą sekwencję znaków. Poprawnym sposobem na spowodowanie, że znak końca linii jest częścią wartości String literału łańcuchowego, jest użycie sekwencji specjalnej, takiej jak \ n lub \ u000A. " - some
Nie widzę powodu, by zrobić to, gdy przeglądarki traktują to niespójnie. "line1 \ n" + "line2" na wielu liniach jest dostatecznie czytelny i masz zagwarantowane spójne zachowanie. - SamStephens


Aktualizacja:

Jak wspomniano w pierwszej odpowiedzi, za pomocą ES6 / Babel można teraz tworzyć wieloliniowe ciągi po prostu używając zwrotnych:

const htmlString = `Say hello to 
multi-line
strings!`;

Zmienne interpolujące to popularna nowa funkcja, która jest wyposażona w łańcuchy z ogranicznikami odsyłającymi:

const htmlString = `${user.name} liked your post about strings`;

To po prostu przechodzi do konkatenacji:

user.name + ' liked your post about strings'

Oryginalna odpowiedź ES5:

Przewodnik po JavaScript w języku JavaScript zaleca używanie łączenia ciągów zamiast ucieczki przed nowymi liniami:

Nie rób tego:

var myString = 'A rather long string of English text, an error message \
                actually that just keeps going and going -- an error \
                message to make the Energizer bunny blush (right through \
                those Schwarzenegger shades)! Where was I? Oh yes, \
                you\'ve got an error and all the extraneous whitespace is \
                just gravy.  Have a nice day.';

Białych spacji na początku każdej linii nie można bezpiecznie usunąć w czasie kompilacji; spacje po ukośniku spowodują trudne błędy; i chociaż większość silników skryptów obsługuje to, to nie jest częścią ECMAScript.

Zamiast tego użyj konkatenacji ciągów:

var myString = 'A rather long string of English text, an error message ' +
               'actually that just keeps going and going -- an error ' +
               'message to make the Energizer bunny blush (right through ' +
               'those Schwarzenegger shades)! Where was I? Oh yes, ' +
               'you\'ve got an error and all the extraneous whitespace is ' +
               'just gravy.  Have a nice day.';

1120
2018-06-06 02:30



to nie działa dla mnie w języku canary dla Windows nawet po włączeniu Experimental JavaScript - Inuart
Nie rozumiem zalecenia Google. Wszystkie przeglądarki, z wyjątkiem bardzo starych, obsługują ukośnik odwrotny, a następnie podejście nowej linii i będą nadal to robić w przyszłości, aby zapewnić kompatybilność wsteczną. Jedynym czasem, w którym musisz tego uniknąć, jest to, że musisz mieć pewność, że na końcu każdej linii dodano tylko jeden znak nowej linii (lub nie dodano nowej linii) (zobacz także mój komentarz dotyczący zaakceptowanej odpowiedzi). - Matt Browne
Ci, którzy chcą wypróbować te rzeczy, koniecznie sprawdź [Chrome Canary] [1] [1]: google.com/intl/en/chrome/browser/canary.html - Sazid
Zwróć uwagę, że ciągi szablonów nie są obsługiwane w IE11, Firefox 31, Chrome 35 lub Safari 7. Zobacz kangax.github.io/compat-table/es6 - Dwayne
@MattBrowne Rekomendacja Google jest już przez nich udokumentowana, według ważności ważnych powodów: (1) Biała spacja na początku każdego wiersza [w przykładzie, nie chcesz tego spacji w swoim łańcuchu, ale wygląda ładniej w kodzie ] (2) białe znaki po ukośniku spowodują błędne błędy [jeśli zakończysz linię \ zamiast "\" trudno zauważyć] i (3) podczas gdy większość silników skryptów obsługuje to, nie jest częścią ECMAScript [tj. po co używać niestandardowych funkcji?] Pamiętaj, że jest to przewodnik po stylu, który polega na ułatwieniu czytania kodu + utrzymaniu + debugowaniu: nie tylko "działa poprawnie". - ShreevatsaR


wzór text = <<"HERE" This Is A Multiline String HERE nie jest dostępny w js (pamiętam, że używam go dużo w moich starych dobrych czasach Perla).

Aby zachować nadzór złożonymi lub długimi ciągami multilinii, czasami używam wzorca tablicowego:

var myString = 
   ['<div id="someId">',
    'some content<br />',
    '<a href="#someRef">someRefTxt</a>',
    '</div>'
   ].join('\n');

lub już pokazany wzór anonimowy (escape newline), który może być brzydkim blokiem w twoim kodzie:

    var myString = 
       '<div id="someId"> \
some content<br /> \
<a href="#someRef">someRefTxt</a> \
</div>';

Oto kolejna dziwna, ale działająca "sztuczka"1:

var myString = (function () {/*
   <div id="someId">
     some content<br />
     <a href="#someRef">someRefTxt</a>
    </div>        
*/}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1];

edycja zewnętrzna: jsfiddle

[dodatek 2015]
ES6 obsługuje łańcuchy ciągłe w wielu liniach przy użyciu ciągi szablonów:

let str = `This is a text
    with multiple lines.
    Escapes are interpreted,
    \n is a newline.`;
let str = String.raw`This is a text
    with multiple lines.
    Escapes are not interpreted,
    \n is not a newline.`;

1 Uwaga: zostanie to utracone po zminimalizowaniu / zaciemnieniu kodu


634
2018-04-30 07:22



Proszę nie używać wzorca tablicowego. W większości przypadków będzie wolniejszy niż zwykłe połączenie ciągów. - BMiner
Naprawdę? jsperf.com/join-concat/24 - KooiInc
Wzorzec macierzy jest bardziej czytelny, a utrata wydajności aplikacji często jest znikoma. Jak pokazuje ten test perfekcji, nawet IE7 może wykonywać dziesiątki tysięcy operacji na sekundę. - Ben Atkin
+1 dla eleganckiej alternatywy, która działa nie tylko w ten sam sposób we wszystkich przeglądarkach, ale jest także odporna na przyszłość. - Pavel
@KooiInc Twoje testy zaczynają się od już utworzonej macierzy, która pochyla wyniki. Jeśli dodasz inicjalizację macierzy, prosta konkatenacja będzie szybsza jsperf.com/string-concat-without-sringbuilder/7 Widzieć stackoverflow.com/questions/51185/... Jako trik dla nowych linii może być OK, ale z pewnością robi więcej pracy, niż powinien - Juan Mendes


ty mogą mają łańcuchy multilinii w czystym JavaScript.

Ta metoda opiera się na serializacji funkcji, która jest zdefiniowane jako zależne od realizacji. Działa w większości przeglądarek (patrz poniżej), ale nie ma gwarancji, że nadal będzie działać w przyszłości, więc nie należy polegać na nim.

Korzystanie z następującej funkcji:

function hereDoc(f) {
  return f.toString().
      replace(/^[^\/]+\/\*!?/, '').
      replace(/\*\/[^\/]+$/, '');
}

Możesz mieć tutaj takie dokumenty:

var tennysonQuote = hereDoc(function() {/*!
  Theirs not to make reply,
  Theirs not to reason why,
  Theirs but to do and die
*/});

Metoda została pomyślnie przetestowana w następujących przeglądarkach (nie wspomniano = nie testowano):

  • IE 4 - 10
  • Opera 9.50 - 12 (nie w 9-)
  • Safari 4 - 6 (nie w 3)
  • Chrome 1 - 45
  • Firefox 17 - 21 (nie w 16-)
  • Rekonq 0,7.0 - 0,8
  • Nie obsługiwane w Konquerorze 4.7.4

Uważaj jednak na swojego minifigurcę. Zwykle usuwa komentarze. Dla Kompresor YUI, komentarz zaczynający się od /*!(jak ten, którego użyłem) zostanie zachowany.

Myślę że real rozwiązaniem byłoby użycie CoffeeScript.


327
2018-04-06 18:16



+ 1 + 1 Sprytny! (działa w Node.JS) - George Bailey
Co!? tworzenie i dekompilowanie funkcji do zhakowania komentarza wielowierszowego w ciąg wielowierszowy? Teraz jest to brzydki. - fforw
Tak naprawdę jest poza brzydki ... Chociaż nie ma dekompilacja zaangażowany... - Jordão
jsfiddle.net/fqpwf działa w Chrome 13 i IE8 / 9, ale nie w FF6. Nienawidzę tego mówić, ale podoba mi się i jeśli to może być intencjonalna funkcja każdej przeglądarki (aby nie zniknęła), użyłbym go. - Jason Kleban
Niezwykle przydatny. Używam go do testów jednostkowych (Jasmine), ale unikam go dla kodu produkcyjnego. - Jason


Możesz to zrobić...

var string = 'This is\n' +
'a multiline\n' + 
'string';

187
2018-03-21 21:05



Pierwszy przykład jest świetny i prosty. Znacznie lepsze niż \ podejście, ponieważ nie jestem pewien, w jaki sposób przeglądarka obsłuży ukośnik odwrotny jako znak ucieczki i jako znak wieloliniowy. - Matt K
Kod CDATA (E4X) jest przestarzały i wkrótce przestanie działać nawet w Firefoksie. - Brock Adams
e4x.js byłoby dobrym rozwiązaniem przyszłościowym - Paul Sweatte


Wymyśliłem tę bardzo jimmowaną, sfałszowaną metodę wielowątkowego sznurka. Ponieważ konwertowanie funkcji na ciąg powoduje również zwrot jakichkolwiek komentarzy w funkcji, możesz użyć komentarzy jako łańcucha przy użyciu wielowierszowego komentarza / ** /. Musisz tylko przyciąć końce i masz strunę.

var myString = function(){/*
    This is some
    awesome multi-lined
    string using a comment 
    inside a function 
    returned as a string.
    Enjoy the jimmy rigged code.
*/}.toString().slice(14,-3)

alert(myString)

107
2018-01-03 19:51



To jest absolutnie przerażające. Uwielbiam to (chociaż może być konieczne dopasowanie do wyrażenia regularnego, ponieważ nie jestem pewien, jak precyzyjne są białe spacje toString() jest. - Kevin Cox
stackoverflow.com/a/5571069/499214 - John Dvorak
To rozwiązanie nie działa w firefoxie, może jest to funkcja zabezpieczająca dla przeglądarki? EDYCJA: Nieważne, nie działa tylko w przeglądarce Firefox w wersji 16. - Bill
Uważaj też na minifiery, które usuwają komentarze ...: D - jondavidjohn
@KevinCox, którego możesz użyć trim(). - schmijos


Jestem zaskoczony, że tego nie widziałem, ponieważ działa wszędzie, gdzie go testowałem i jest bardzo przydatny dla np. szablony:

<script type="bogus" id="multi">
    My
    multiline
    string
</script>
<script>
    alert($('#multi').html());
</script>

Czy ktoś wie o środowisku, w którym jest HTML, ale nie działa?


82
2017-08-17 14:25



Wszędzie tam, gdzie nie chcesz umieszczać struny w oddzielnych i odległych elementach scenariusza. - Lodewijk
Ważny sprzeciw! To nie jest doskonałe. Ale w przypadku szablonów ten rozdział jest nie tylko w porządku, ale może nawet zachęcony. - Peter V. Mørch
Wolę dzielić wszystko na ponad 80/120 znaków na multilinię, obawiam się, że to coś więcej niż szablony. Teraz wolę składnię "line1" + "line2". Jest także najszybszy (choć może to rywalizować z naprawdę dużymi tekstami). To fajna sztuczka. - Lodewijk
właściwie to jest HTML, a nie JavaScript: - / - CpILL
jednak zadanie uzyskania wielowierszowego łańcucha znaków w javascript można zrobić w ten sposób - Davi Fiamenghi


Rozwiązałem to przez wyprowadzenie elementu div, dzięki czemu jest on ukryty i wywołanie id div przez jQuery, kiedy go potrzebowałem.

na przykład

<div id="UniqueID" style="display:none;">
     Strings
     On
     Multiple
     Lines
     Here
</div>

Następnie, gdy potrzebuję uzyskać ciąg, używam następującego jQuery:

$('#UniqueID').html();

Który zwraca mój tekst na wielu liniach. Jeśli zadzwonię

alert($('#UniqueID').html());

Dostaję:

enter image description here


46
2017-08-23 18:30



Dzięki za to! Jest to jedyna odpowiedź, którą znalazłem, która rozwiązuje mój problem, który obejmuje nieznane ciągi znaków, które mogą zawierać dowolną kombinację pojedynczych i podwójnych cudzysłowów wstawianych bezpośrednio do kodu bez możliwości wstępnego kodowania. (pochodzi z języka szablonowego, który tworzy JS - nadal z zaufanego źródła, a nie z formularza, więc nie jest TOTALNIE obłąkany). - octern
To była jedyna metoda, która zadziałała dla mnie, aby utworzyć wielowątkową zmienną łańcuchową javascript ze stringów Java. - beginner_
Co jeśli łańcuch jest HTML? - Dan Dascalescu
$ ('# UniqueID'). Content () - mplungjan
@Pacerier Wszystko, co czytałem, od Google, a także innych witryn, mówi, że obecnie Google indeksuje display:none treść, najprawdopodobniej ze względu na popularność interfejsów JavaScript w stylu. (Na przykład strona z najczęściej zadawanymi pytaniami z funkcją ukrywania / pokazywania). Musisz jednak zachować ostrożność, ponieważ Google twierdzi, że może cię ukarać, jeśli ukryta zawartość zostanie zaprojektowana tak, by sztucznie zawyżać twoje rankingi SEO. - Gavin


Używanie znaczników skryptów:

  • dodać <script>...</script> blok zawierający tekst wielowierszowy do head etykietka;
  • pobierz tekst wielowierszowy jak ... (uważaj na kodowanie tekstu: UTF-8, ASCII)

    <script>
    
        // pure javascript
        var text = document.getElementById("mySoapMessage").innerHTML ;
    
        // using JQuery's document ready for safety
        $(document).ready(function() {
    
            var text = $("#mySoapMessage").html(); 
    
        });
    
    </script>
    
    <script id="mySoapMessage" type="text/plain">
    
        <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:typ="...">
           <soapenv:Header/>
           <soapenv:Body>
              <typ:getConvocadosElement>
                 ...
              </typ:getConvocadosElement>
           </soapenv:Body>
        </soapenv:Envelope>
    
        <!-- this comment will be present on your string -->
        //uh-oh, javascript comments...  SOAP request will fail 
    
    
    </script>
    

27
2018-05-26 09:34



Sądzę, że ta strategia jest czysta i zdecydowanie niedostatecznie wykorzystana. jsrender używa tego. - xdhmoore
Używam tego z innerText iso innerHTML, Ale jak mam się upewnić, że białe spacje są zachowane? - David Nouls
Ponieważ mydło jest oparte na XML, musi je zachować <![CDATA[.....]]> . - jpfreire
Również zapytania ajaxowe na wypadek, gdybyś ich używał. Możesz spróbować zmienić nagłówki xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); Nie pamiętam o innych problemach niż pomylenie komentarzy w JS. Miejsca bez problemów. - jpfreire