119

我需要像 JavaScript 中的 heredoc 这样的东西。你对此有什么想法吗?我需要跨浏览器功能。

我找到了这个:

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

我认为这对我有用。:)

4

14 回答 14

98

试试ES6 String Template,你可以做类似的事情

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


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

=> true

即使在带有TypeScript的旧浏览器中,您也可以使用这个强大的功能

于 2015-01-10T10:25:00.417 回答
65

不,不幸的是 JavaScript 不支持像 heredoc 这样的东西。

于 2010-12-07T12:16:14.600 回答
39

这个怎么样:

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*/”。

于 2013-01-19T16:19:07.847 回答
34

基于 Zv_oDD 的回答,我创建了一个类似的函数以便于重用。

警告:这是许多 JS 解释器的非标准功能,可能会在某些时候被删除,但由于我正在构建一个仅在 Chrome 中使用的脚本,所以我正在使用它!永远不要依赖于面向客户的网站!

// 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 - 更改为完全不与函数原型混淆,而是使用名称 heredoc。

5/26/2017 - 更新了空格以反映现代编码标准。

于 2013-01-24T08:09:42.417 回答
19

根据您运行的 JS/JS 引擎的风格(SpiderMonkey、AS3),您可以简单地编写内联 XML,您可以在其中放置多行文本,例如 heredoc:

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

console.log(xml.toXMLString())
console.log(xml.toString()) // just gets the content
于 2012-02-23T00:29:02.610 回答
15

ES6模板字符串具有 heredoc 功能。

您可以声明由反引号 (` `) 括起来的字符串,并且可以通过多行进行扩展。

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"

实际上,其中还有更多功能,例如 Tagged Temple Strings 和 Raw Strings。请在以下位置找到文档

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

于 2015-11-17T16:10:13.773 回答
10

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
于 2019-05-07T22:31:48.640 回答
9

我觉得仅仅为@NateFerrero 的答案的扩展写一个单独的答案很糟糕,但我也不觉得编辑他的答案是合适的,所以如果这个答案对你有用,请投票给@NateFerrero。

tl;dr-对于那些希望他们的heredoc中使用块评论的人......

我主要需要 Javascript heredocs 来存储 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,不幸的是(正如语法高亮所暗示的那样)第一个*/结束了整体评论,打破了 heredoc。


对于这个特定目的(CSS),我的解决方法是添加

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

到@NateFerrero's 内的链条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只需找到/* ... * /并删除要创建的空间,/* ... */从而保留heredoc,直到被调用。


您当然可以使用完全删除评论

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

//如果您将评论添加到链中,您还可以支持评论:

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

*此外,除了and之间的单个空格之外,您还可以执行其他操作/,例如-

    /**
     * Nuke rounded corners.
     *-/

如果您只是适当地更新正则表达式:

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

或者,也许您想要任意数量的空白而不是单个空格?

.replace(/(\/\*[\s\S]*?\*)\s+\//g, '$1/')
                          ^^^
于 2014-02-14T20:57:20.710 回答
8

你可以使用CoffeeScript,一种编译成 JavaScript 的语言。代码一对一编译成等价的JS,运行时没有解释。

当然,它有heredocs :)

于 2010-12-07T12:21:39.087 回答
3

正如其他人所说,ES6 模板字符串为您提供了传统 heredocs 提供的大部分内容。

如果您想更进一步并使用标记的模板字符串,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.
  `)
}
于 2019-01-30T15:26:40.037 回答
1

你可以使用 Sweet.js 宏来添加它,就像Tim Disney 在这篇文章中创建的那样

请注意,此方法使用反引号作为字符串分隔符:

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`
于 2014-08-09T12:25:20.897 回答
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/

于 2015-03-25T21:11:02.583 回答
0

我发布这个版本是因为它避免了将正则表达式用于如此微不足道的事情。

恕我直言,正则表达式是一种混淆,它是作为 perl 开发人员之间的恶作剧而创建的。社区的其他人认真对待它们,几十年后我们现在付出了代价。不要使用正则表达式,除了与遗留代码的向后兼容性。如今,没有任何借口可以编写人类无法立即阅读和理解的代码。正则表达式在各个层面都违反了这一原则。

我还添加了一种将结果添加到当前页面的方法,而不是要求这样做。

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>

于 2019-05-18T22:24:42.707 回答
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)
于 2015-10-02T20:50:08.533 回答