जावास्क्रिप्ट हेरेडोक


109

मुझे जावास्क्रिप्ट में heredoc की तरह कुछ चाहिए। क्या आपके पास इसके लिए कोई विचार है? मुझे क्रॉस-ब्राउज़र कार्यक्षमता की आवश्यकता है।

मुझे मिला:

heredoc = '\
<div>\
    <ul>\
        <li><a href="#zzz">zzz</a></li>\
    </ul>\
</div>';

मुझे लगता है कि यह मेरे लिए काम करेगा। :)


6
का डुप्लीकेट stackoverflow.com/questions/805107/... जो कुछ और विस्तृत जवाब है।
चाडविक

4
"\" को जोड़ने से मुझे हर बार फ्रॉड हो जाता है। Imho, बहुस्तरीय तार के लिए सामान्य वाक्यविन्यास नहीं होना पूरी तरह से अनुचित है। और वे इसे किसी भी संस्करण में जोड़ सकते थे, लेकिन उन्होंने ऐसा नहीं किया।
लेक्स


आजकल, यह टेम्प्लेट शाब्दिक के साथ किया जाता है जैसा कि संभावित डुप्लिकेट में दिखाया गया है (यहां कोई अद्यतन उत्तर नहीं है)।
ब्रासोफिलो

जवाबों:


77

ES6 स्ट्रिंग टेम्पलेट का प्रयास करें , आप कुछ ऐसा कर सकते हैं

var hereDoc = `
This
is
a
Multiple
Line
String
`.trim()


hereDoc == 'This\nis\na\nMultiple\nLine\nString'

=> true

आप इस महान सुविधा का उपयोग आज 6to5 या टाइपस्क्रिप्ट के साथ कर सकते हैं


2
यह तब लागू होता है जब आप सिर्फ मल्टी-लाइन स्ट्रिंग्स चाहते थे। हालाँकि, चूंकि आप वास्तव में अपने स्ट्रिंग को संलग्न करने वाले प्रतीक को नहीं बदल सकते हैं, यह वास्तव में वंशानुगत नहीं है।
पीयूष कुशवाहा

3
नोट के रूप में, मूल प्रश्न 5 साल पहले ES6 उपलब्ध होने से पहले पूछा गया था। यह सबसे अच्छा अभ्यास है जो आगे बढ़ रहा है क्योंकि प्रदर्शन बेहतर है।
हेनरी त्सेंग

2
@HenryTseng, तो क्या आप सुझाव दे रहे हैं कि इस प्रश्न के उत्तर 5 साल पहले मौजूद प्राचीन तकनीकों के अनुरूप होने चाहिए? यदि प्रश्न अभी भी खुला है, तो यह नई प्रौद्योगिकियों का लाभ लेने के योग्य है, जैसा कि वे समय के साथ बनाए गए हैं। इस तरह, एक ही समस्या वाले नए उपयोगकर्ता यहां "गैर-पुरातात्विक" जानकारी पा सकते हैं।
asiby

1
नहीं, मैं एक टिप्पणी कर रहा था कि क्यों वह समाधान पहले अधिक प्रमुख नहीं था। ऐसा लगता है कि अगर कोई अनुकूलता समस्या नहीं है तो निश्चित रूप से आगे बढ़ने का समर्थन तरीका है।
हेनरी त्सेंग

63

नहीं, दुर्भाग्य से जावास्क्रिप्ट heredoc जैसी किसी भी चीज़ का समर्थन नहीं करता है।


12
मुझे पता है लेकिन मुझे आशा है कि
हेरेडोक

पार्स फ़ंक्शन की टिप्पणियों की तरह कुछ (लेकिन यह काम नहीं है / फ़ायरफ़ॉक्स में) =
VeroLom

37

इस बारे में कैसा है:

function MyHereDoc(){
/*HERE
<div>
   <p>
      This is written in the HEREDOC, notice the multilines :D.
   </p>
   <p>
      HERE
   </p>
   <p>
      And Here
   </p>
</div>
HERE*/
    var here = "HERE";
    var reobj = new RegExp("/\\*"+here+"\\n[\\s\\S]*?\\n"+here+"\\*/", "m");
    str = reobj.exec(MyHereDoc).toString();
    str = str.replace(new RegExp("/\\*"+here+"\\n",'m'),'').toString();
    return str.replace(new RegExp("\\n"+here+"\\*/",'m'),'').toString();
}

//Usage 
document.write(MyHereDoc());

बस पसंद के शब्द के साथ "/ * HERE" और "HERE * /" बदलें।


4
क्या सभी ब्राउज़र / इंजन फंक्शन में टिप्पणियों को लौटाते हैं। String ()? यह बहुत चालाक है
gcb

क्रोम के कंसोल में काम करता है
ओम

4
यदि आपके पास */अपने वंशानुगत में कोई टिप्पणी नहीं है तो काम नहीं करेगा ।
नारिगो

2
मैं नैट फेरेरो के उत्तर का उपयोग करने की सलाह दूंगा, क्योंकि उनका अधिक परिष्कृत और अनुकूलित उदाहरण है। मेरा 3 अलग regEx कॉल का उपयोग करता है और अवधारणा के सबूत के अधिक है।
Zv_oDD

1
बहुत चालाक ... लेकिन आप यह गारंटी नहीं दे सकते कि यह भविष्य में काम करेगा। यह एक अच्छा अभ्यास होने के लिए कार्यान्वयन-निर्भर है।
पियरे-ओलिवियर वार्स

33

Zv_oDD के उत्तर पर निर्माण, मैंने आसान पुन: उपयोग के लिए एक समान कार्य बनाया।

चेतावनी: यह कई जेएस दुभाषियों की एक गैर-मानक विशेषता है, और शायद किसी बिंदु पर हटा दिया जाएगा, लेकिन जैसा कि मैं केवल क्रोम में उपयोग किए जाने के लिए एक स्क्रिप्ट का निर्माण कर रहा हूं, मैं इसका उपयोग कर रहा हूं! क्लाइंट-फेसिंग वेबसाइटों के लिए कभी भी इस पर भरोसा न करें !

// Multiline Function String - Nate Ferrero - Public Domain
function heredoc(fn) {
  return fn.toString().match(/\/\*\s*([\s\S]*?)\s*\*\//m)[1];
};

उपयोग:

var txt = heredoc(function () {/*
A test of horrible
Multi-line strings!
*/});

यह दिखाता है:

"A test of horrible
Multi-line strings!"

टिप्पणियाँ:

  1. टेक्स्ट को दोनों सिरों पर ट्रिम किया गया है, इसलिए दोनों सिरों पर कोई भी अतिरिक्त व्हाट्सएप ठीक है।

संपादन:

2/2/2014 - फ़ंक्शन प्रोटोटाइप के साथ बिल्कुल भी गड़बड़ न करने और इसके बजाय नाम हेरेडोक का उपयोग करने के लिए परिवर्तित किया गया।

5/26/2017 - आधुनिक कोडिंग मानकों को प्रतिबिंबित करने के लिए अपडेटेड व्हाट्सएप।


1
मैं अपने फ़ंक्शन नाम के रूप में यहां () का उपयोग करूंगा, लेकिन इस कोड ने क्रोम की कंसोल में एक चर में मेरे 40k लाइन लॉग डंप को ठीक से काम किया
Omn

आप एक फ़ंक्शन का एक उदाहरण क्यों बनाएंगे और पदावनत संपत्ति __ प्रोटो __ तक पहुंच सकते हैं? क्यों न केवल फ़ंक्शन .prototyp.str = फ़ंक्शन () {...}?
जॉन कुरलक

@JohnKurlak जो और भी बेहतर है! मुझे नहीं लगता कि मुझे पता था कि जब मैंने उत्तर लिखा था तो यह संभव था।
नैट फेरेरो

2
@NateFerrero - बहुत बढ़िया जवाब, धन्यवाद! एक अलग उत्तर के रूप में मेरा खुद का एक एक्सटेंशन जोड़ा गया।
एंड्रयू चींग

मेरे एंड्रॉइड पर, नेक्सस 4, 5.0.1 पर चल रहा है, यह अब क्रोम पर काम नहीं करता है। किसी कारण से, यह व्हाट्सएप और टिप्पणियों को हटा रहा है। अगर यह एक सेटिंग है, तो मैं यह पता नहीं लगा सकता, लेकिन यह निश्चित रूप से क्लाइंट की तरफ है। वर्कअराउंड के लिए कोई विचार?
MLU

19

जेएस / जेएस इंजन आपके द्वारा चलाए जा रहे (स्पाइडरमोंक, एएस 3) के किस स्वाद के आधार पर आप केवल इनलाइन XML लिख सकते हैं, जिसमें आप कई लाइनों पर टेक्स्ट को heredoc की तरह रख सकते हैं:

var xml = <xml>
    Here 
    is 
    some 
    multiline 
    text!
</xml>

console.log(xml.toXMLString())
console.log(xml.toString()) // just gets the content

13

ES6 टेम्प्लेट स्ट्रिंग्स में हेरेडोक सुविधा है।

आप बैक-टिक (``) द्वारा संलग्न तारों की घोषणा कर सकते हैं और कई लाइनों के माध्यम से विस्तारित किया जा सकता है।

var str = `This is my template string...
and is working across lines`;

आप टेम्प्लेट स्ट्रिंग्स के अंदर के भावों को भी शामिल कर सकते हैं। ये डॉलर चिन्ह और घुंघराले ब्रेस ( ${expression}) द्वारा दर्शाए गए हैं ।

var js = "Java Script";
var des = `Template strings can now be used in ${js} with lot of additional features`;

console.log(des); //"Template strings can now be used in Java Script with lot of additional features"

वास्तव में इसमें और भी विशेषताएं हैं जैसे कि टेंपल टेम्पल स्ट्रिंग्स और रॉ स्ट्रिंग्स। कृपया दस्तावेज़ ढूंढे

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings


8

मुझे @ NateFerrero के उत्तर के विस्तार के लिए एक अलग उत्तर लिखने में बुरा लग रहा है , लेकिन मुझे नहीं लगता कि उनका उत्तर संपादित करना उचित है, इसलिए कृपया upNote @NateFerrero को उत्तर दें यदि यह उत्तर आपके लिए उपयोगी था।

tl; dr- उन लोगों के लिए जो अपने heredoc के अंदर ब्लॉक कमेंट्स का उपयोग करना चाहते हैं ...

मुझे मुख्य रूप से CSS के एक ब्लॉक को स्टोर करने के लिए जावास्क्रिप्ट हेरेडोक्स की आवश्यकता है, जैसे

var css = heredoc(function() {/*
    /**
     * Nuke rounded corners.
     */
    body div {
        border-top-left-radius: 0 !important;
        border-top-right-radius: 0 !important;
        border-bottom-right-radius: 0 !important;
        border-bottom-left-radius: 0 !important;
    }
*/});

जैसा कि आप देख सकते हैं, मैं अपने सीएसएस पर टिप्पणी करना पसंद करता हूं, और दुर्भाग्य से (सिंटैक्स हाइलाइटिंग द्वारा संकेत दिया गया) पहले */समग्र टिप्पणी को समाप्त करता है, हेरेडोक को तोड़ता है।


इस विशिष्ट उद्देश्य (CSS) के लिए, मेरा समाधान जोड़ना था

.replace(/(\/\*[\s\S]*?\*) \//g, '$1/')

@ NateFerrero के अंदर श्रृंखला के लिए heredoc; पूर्ण रूप में:

function heredoc (f) {
    return f.toString().match(/\/\*\s*([\s\S]*?)\s*\*\//m)[1].replace(/(\/\*[\s\S]*?\*) \//g, '$1/');
};

और जो अंतरिक्ष जोड़कर इसका इस्तेमाल *और/ "आंतरिक" ब्लॉक टिप्पणियों के लिए , जैसे:

var css = heredoc(function() {/*
    /**
     * Nuke rounded corners.
     * /
    body div {
        border-top-left-radius: 0 !important;
        border-top-right-radius: 0 !important;
        border-bottom-right-radius: 0 !important;
        border-bottom-left-radius: 0 !important;
    }
*/});

replaceबस पाता है /* ... * /और बनाने के लिए अंतरिक्ष को हटा/* ... */ , जिससे हियरडॉक संरक्षण जब तक कहा जाता है।


आप निश्चित रूप से टिप्पणियों का उपयोग पूरी तरह से हटा सकते हैं

.replace(/\/\*[\s\S]*?\* \//g, '')

//यदि आप उन्हें श्रृंखला में जोड़ते हैं तो आप टिप्पणियों का समर्थन भी कर सकते हैं :

.replace(/^\s*\/\/.*$/mg, '')

इसके अलावा, आप के बीच एक रिक्त स्थान के अलावा अन्य कुछ कर सकते हैं *और /एक तरह -:

    /**
     * Nuke rounded corners.
     *-/

यदि आप उचित रूप से regex को अपडेट करते हैं:

.replace(/(\/\*[\s\S]*?\*)-\//g, '$1/')
                          ^

या हो सकता है कि आप सिंगल स्पेस के बजाय व्हॉट्सएप की मनमानी रकम चाहें?

.replace(/(\/\*[\s\S]*?\*)\s+\//g, '$1/')
                          ^^^

2
ठंडा! यह मेरी विधि के साथ एक ज्ञात सीमा थी, मुझे यह पसंद है :)
नैट फेरेरो

8

आप जावास्क्रिप्ट को संकलित करने वाली भाषा CoffeeScript का उपयोग कर सकते हैं । कोड एक-से-एक समतुल्य जेएस में संकलित करता है, और रनटाइम पर कोई व्याख्या नहीं है।

और हां, यह heredocs है :)


24
सही उत्तर नहीं है। कॉफीस्क्रिप्ट और ईजेएस को सुझावों के रूप में इस्तेमाल किया जा सकता है।
alvincrespo

4
कॉफ़ीस्क्रिप्ट मेरे द्वारा सामना किए गए अधिकांश जेएस मुद्दों का सही उत्तर है। यदि आप जेएस की एक तुच्छ राशि से अधिक लिखते हैं (और आप अपने समय और ऊर्जा को महत्व देते हैं) तो आप इसे उपयोग करने के लिए खुद पर निर्भर करते हैं।
ब्रैंडन

5
मुझे लगता है कि यह एक अच्छा उत्तर है क्योंकि यह जावास्क्रिप्ट में हेरेडोक की अनुपस्थिति को दरकिनार करने का एक आसान तरीका प्रदान करता है। मुझे बहुत समय बचाया।
स्टोकेक

3
यदि आप सिर्फ js का एक हिस्सा चाहते हैं, लेकिन वास्तव में इसे लिखने के साथ सौदा नहीं करना चाहते हैं: coffeescript.org और "Coffeescript" बटन का उपयोग करें।
जौलम

1
यह उच्चतम श्रेणी के एक से अधिक उत्तर है, जो मूल रूप से सिर्फ ... "नहीं" है। मुझे इस तरह के जवाबों से नफरत है।
मैट फ्लेचर

7

ES5 और पहले के संस्करण

(function(){/**
some random
multi line
text here
**/}).toString().slice(15,-5);

ES6 और बाद के संस्करण

`some random
multi line
text here`

परिणाम

some random
multi line
text here

सबसे अच्छा जवाब
बेंजामिन

1
पुरानी शैली की बात एक अविश्वसनीय रूप से क्रूर हैक है: /
Shayne

1

आप इस पोस्ट में टिम डिज्नी द्वारा बनाई गई के रूप में इसे जोड़ने के लिए Sweet.js मैक्रोज़ का उपयोग कर सकते हैं

ध्यान दें कि यह दृष्टिकोण backticks का उपयोग स्ट्रिंग सीमांकक के रूप में करता है:

let str = macro {
    case {_ $template } => {
        var temp = #{$template}[0];
        var tempString = temp.token.value.raw;
        letstx $newTemp = [makeValue(tempString, #{here})];
        return #{$newTemp}
    }
}

str `foo bar baz`

1

जैसा कि दूसरों ने कहा है, ES6 टेम्पलेट स्ट्रिंग्स आपको सबसे अधिक देते हैं जो पारंपरिक हेरेडोक्स प्रदान करते हैं।

यदि आप एक कदम और आगे जाना चाहते हैं और टैग किए गए टेम्पलेट स्ट्रिंग का उपयोग करना चाहते हैं, theredocतो एक अच्छा उपयोगिता फ़ंक्शन है जो आपको ऐसा करने देता है:

if (yourCodeIsIndented) {
  console.log(theredoc`
    Theredoc will strip the
    same amount of indentation
    from each line.

      You can still indent
      further if you want.

    It will also chop off the
    whitespace-only first and
    last lines.
  `)
}

0

यदि आपके हाथ में कुछ html और jQuery हैं और स्ट्रिंग मान्य HTML है, तो यह उपयोगी हो सकता है:

<div id="heredoc"><!--heredoc content
with multiple lines, even 'quotes' or "double quotes",
beware not to leave any tag open--></div>
<script>
var str = (function() {
   var div = jQuery('#heredoc');
   var str = div.html();
   str = str.replace(/^<\!--/, "").toString();
   str = str.replace(/-->$/, "").toString();
   return str;
})();
</script>

यदि पाठ में बीच में "<! ->>" टिप्पणियां हैं, तो यह भी काम करता है, लेकिन पाठ का एक हिस्सा दिखाई दे सकता है। यहाँ की फिडेल है: https://jsfiddle.net/hr6ar152/1/


0
// js heredoc - http://stackoverflow.com/a/32915549/466363
// a function with comment with eval-able string, use it just like regular string

function extractFuncCommentString(func,comments) {
  var matches = func.toString().match(/function\s*\(\)\s*\{\s*\/\*\!?\s*([\s\S]+?)\s*\*\/\s*\}/);
  if (!matches) return undefined;
  var str=matches[1];

   // i have made few flavors of comment removal add yours if you need something special, copy replacement lines from examples below, mix them
  if(comments===1 )
  {
   // keep comments, in order to keep comments  you need to convert /**/ to / * * / to be able to put them inside /**/ like /*    / * * /    */
   return (
    str
   .replace(/\/\s\*([\s\S]*?)\*\s\//g,"/*$1*/") //       change   / * text * /  to   /* text */ 
   )
  }
  else if(comments===2)
  {
   // keep comments and replace singleline comment to multiline comment
   return (
    str
   .replace(/\/\s\*([\s\S]*?)\*\s\//g,"/*$1*/") //       change   / * text * /  to   /* text */ 
   .replace(/\/\/(.*)/g,"/*$1*/")          //           change   //abc to  /*abc*/
   )
  }
  else if(comments===3)
  {
   // remove comments
   return (
      str
      .replace(/\/\s\*([\s\S]*?)\*\s\//g,"") //       match / * abc * /
      .replace(/\/\/(.*)/g,"")             // match //abc
     )
  }
  else if(comments===4)
  {
   // remove comments and trim and replace new lines with escape codes
   return (
      str
      .replace(/\/\s\*([\s\S]*?)\*\s\//g,"") //       match / * abc * /
      .replace(/\/\/(.*)/g,"")             // match //abc
      .trim() // after removing comments trim and:
      .replace(/\n/g,'\\n').replace(/\r/g,'\\r') // replace new lines with escape codes. allows further eval() of the string, you put in the comment function: a quoted text but with new lines
     )
  }
  else if(comments===5)
  {
   // keep comments comments and replace strings, might not suit when there are spaces or comments before and after quotes 
   // no comments allowed before quotes of the string
   return (
      str
      .replace(/\/\s\*([\s\S]*?)\*\s\//g,"/*$1*/") //       change   / * text * /  to   /* text */
      .replace(/\/\/(.*)/g,"/*$1*/")          //           change   //abc to  /*abc*/
      .trim() // trim space around quotes to not escape it and:
      .replace(/\n/g,'\\n').replace(/\r/g,'\\r') // replace new lines with escape codes. allows further eval() of the string, you put in the comment function: a quoted text but with new lines
     )
  }
  else 
  return str
}

उदाहरण

var week=true,b=123;
var q = eval(extractFuncCommentString(function(){/*!

// this is a comment     


'select 

/ * this
is a multiline 
comment * /

 a
,b  // this is a comment  
,c
from `table`
where b='+b+' and monthweek="'+(week?'w':'m')+'" 
//+' where  a=124
order by a asc
'
*/},4));

कैश के साथ: - एक साधारण टेम्पलेट फ़ंक्शन करें, और फ़ंक्शन को सहेजें: (दूसरी बार तेजी से काम करता है)

var myfunction_sql1;
function myfunction(week,a){


    if(!myfunction_sql1) eval('myfunction_sql1=function(week,a){return ('+extractFuncCommentString(function(){/*!
'select 

/ * this
is a multiline 
comment * /

 a
,b  // this is a comment  
,c
from `table`
where b='+b+' and monthweek="'+(week?'w':'m')+'" 
//+' where  a=124
order by a asc

'*/},4)+')}');
    q=myfunction_sql1(week,a);
    console.log(q)
}
myfunction(true,1234)

1
एफएफ और क्रोम में अलग-अलग परिणाम।
डेव न्यूटन

क्या अलग है? बस क्रोम और एफएफ में परीक्षण किया गया है और मुझे बिल्कुल समान परिणाम मिलते हैं। सिवाय इसके कि क्रोम में क्रोम के कंसोल में कोई नयापन नहीं है। लेकिन चर एक ही है। यह
कंसोल के

0

मैं इस संस्करण को पोस्ट कर रहा हूं क्योंकि यह कुछ तुच्छ के लिए regex के उपयोग से बचा जाता है।

IMHO रेगेक्स एक आक्षेप है जो पर्ल डेवलपर्स के बीच एक व्यावहारिक मजाक के रूप में बनाया गया था। बाकी समुदाय ने उन्हें गंभीरता से लिया और अब हम कीमत चुकाते हैं, दशकों बाद। रेगेक्स का उपयोग न करें, सिवाय विरासत कोड के साथ पिछड़े हमदर्दी के लिए। कोड लिखने के लिए इन दिनों कोई बहाना नहीं है जो तुरंत मानव पठनीय और समझने योग्य नहीं है। regex इस सिद्धांत का हर स्तर पर उल्लंघन करता है।

मैंने वर्तमान पृष्ठ पर परिणाम जोड़ने का एक तरीका भी जोड़ा है, न कि यह कि इसके लिए कहा गया था।

function pretty_css () {
/*
    pre { color: blue; }

*/
}
function css_src (css_fn) {
   var css = css_fn.toString();
   css = css.substr(css.indexOf("/*")+2);
   return css.substr(0,css.lastIndexOf("*/")).trim();
}

function addCss(rule) {
  let css = document.createElement('style');
  css.type = 'text/css';
  if (css.styleSheet) css.styleSheet.cssText = rule; // Support for IE
  else css.appendChild(document.createTextNode(rule)); // Support for the rest
  document.getElementsByTagName("head")[0].appendChild(css);
}

addCss(css_src(pretty_css));

document.querySelector("pre").innerHTML=css_src(pretty_css);
<pre></pre>

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.