【发布时间】:2019-04-24 17:21:01
【问题描述】:
我在 Ruby 中有以下代码。我想将此代码转换为 JavaScript。 JS中的等价代码是什么?
text = <<"HERE"
This
Is
A
Multiline
String
HERE
【问题讨论】:
标签: javascript string multiline heredoc
我在 Ruby 中有以下代码。我想将此代码转换为 JavaScript。 JS中的等价代码是什么?
text = <<"HERE"
This
Is
A
Multiline
String
HERE
【问题讨论】:
标签: javascript string multiline heredoc
在这里找到了很多过度设计的答案。 我认为最好的两个答案是:
1:
let str = `Multiline string.
foo.
bar.`
最终记录:
Multiline string.
foo.
bar.
2:
let str = `Multiline string.
foo.
bar.`
如果 str 嵌套在函数/对象等中,它会正确记录它,但它在脚本文件中很难看......:
Multiline string.
foo.
bar.
我对正确记录 str 的正则表达式的非常简单的回答:
let str = `Multiline string.
foo.
bar.`.replace(/\n +/g, '\n');
请注意,这不是完美的解决方案,但如果您确定在新行 (\n) 之后至少会出现一个空格(+ 表示至少出现一次),它就会起作用。它也适用于 *(零个或多个)。
您可以更明确地使用 {n,},这意味着至少出现 n 次。
【讨论】:
在 2015 年引入 ES6 以及模板文字之前,JavaScript 从来没有真正好的方法来处理多行字符串。
模板文字是由反引号(``) 分隔的字符串,而不是普通的单引号 ('')/双引号 ("")e 分隔符。
【讨论】:
Ruby produce: "This\nIs\nA\nMultiline\nString\n" - 下面的 JS 产生完全相同的字符串
text = `This
Is
A
Multiline
String
`
// TEST
console.log(JSON.stringify(text));
console.log(text);
这是对Lonnie Best answer 的改进,因为他的答案中的换行符与 ruby 输出中的位置不完全相同
【讨论】:
\n 的确切位置(与 ruby 输出(答案中链接的工作示例)进行比较)-这是 Lonnie 答案的改进,因为他的答案中的换行符与 ruby 输出中的位置不完全相同
您可以在纯 JavaScript 中使用多行字符串。
该方法是基于函数的序列化,即defined to be implementation-dependent。它在大多数浏览器中都可以工作(见下文),但不能保证它在将来仍然可以工作,所以不要依赖它。
使用以下函数:
function hereDoc(f) {
return f.toString().
replace(/^[^\/]+\/\*!?/, '').
replace(/\*\/[^\/]+$/, '');
}
你可以有这样的文件:
var tennysonQuote = hereDoc(function() {/*!
Theirs not to make reply,
Theirs not to reason why,
Theirs but to do and die
*/});
该方法已在以下浏览器中成功测试(未提及=未测试):
不过,请小心使用您的缩小器。它倾向于删除 cmets。对于YUI compressor,将保留以/*! 开头的注释(就像我使用的那样)。
我认为真正的解决方案是使用CoffeeScript。
ES6 更新:您可以使用反引号而不是创建带有注释的函数并在注释上运行 toString。正则表达式需要更新为仅去除空格。您还可以使用字符串原型方法来执行此操作:
let foo = `
bar loves cake
baz loves beer
beer loves people
`.removeIndentation()
应该有人写这个 .removeIndentation 字符串方法... ;)
【讨论】:
您可以使用标记模板来确保获得所需的输出。
例如:
// Merging multiple whitespaces and trimming the output
const t = (strings) => { return strings.map((s) => s.replace(/\s+/g, ' ')).join("").trim() }
console.log(t`
This
Is
A
Multiline
String
`);
// Output: 'This Is A Multiline String'
// Similar but keeping whitespaces:
const tW = (strings) => { return strings.map((s) => s.replace(/\s+/g, '\n')).join("").trim() }
console.log(tW`
This
Is
A
Multiline
String
`);
// Output: 'This\nIs\nA\nMultiline\nString'
【讨论】:
反对者:此代码仅供参考。
这已经在 Mac 上的 Fx 19 和 Chrome 24 中测试过
var new_comment; /*<<<EOF
<li class="photobooth-comment">
<span class="username">
<a href="#">You</a>:
</span>
<span class="comment-text">
$text
</span>
@<span class="comment-time">
2d
</span> ago
</li>
EOF*/
// note the script tag here is hardcoded as the FIRST tag
new_comment=document.currentScript.innerHTML.split("EOF")[1];
document.querySelector("ul").innerHTML=new_comment.replace('$text','This is a dynamically created text');
<ul></ul>
【讨论】:
规则是:在字符串中,在需要换行的地方使用 \n;您不必在 \n 之前或之后放置空格,JavaScript 的解释器足够聪明,可以知道不可打印字符表示的长度。
【讨论】:
【讨论】:
正如第一个答案提到的,使用 ES6/Babel,您现在可以通过使用反引号来创建多行字符串:
const htmlString = `Say hello to
multi-line
strings!`;
插值变量是一种流行的新功能,带有反引号分隔的字符串:
const htmlString = `${user.name} liked your post about strings`;
这只是转译为串联:
user.name + ' liked your post about strings'
Google's JavaScript style guide 建议使用字符串连接而不是转义换行符:
不要这样做:
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.';每行开头的空格不能在编译时安全地去除;斜杠后的空格会导致棘手的错误;虽然大多数脚本引擎都支持这一点,但它不是 ECMAScript 的一部分。
改用字符串连接:
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.';
【讨论】:
\ 而不是 `\` 结束一行,则很难注意到] 和 (3) 虽然大多数脚本引擎都支持这个,它不是 ECMAScript 的一部分 [即为什么要使用非标准功能?] 请记住,它是一个风格指南,它是关于使代码易于阅读+维护+调试:不仅仅是“它工作”正确。
在 Javascrips 中创建多行字符串的最简单方法是使用反引号 ( `` )。这允许您创建多行字符串,您可以在其中插入带有${variableName} 的变量。
let name = 'Willem';
let age = 26;
let multilineString = `
my name is: ${name}
my age is: ${age}
`;
console.log(multilineString);
ES6//es2015中介绍过
【讨论】:
text = <<"HERE" This Is A Multiline String HERE 模式在 js 中不可用(我记得在我以前的 Perl 时代经常使用它)。
为了监督复杂或长的多行字符串,我有时会使用数组模式:
var myString =
['<div id="someId">',
'some content<br />',
'<a href="#someRef">someRefTxt</a>',
'</div>'
].join('\n');
或者匿名模式已经显示(转义换行符),这可能是您代码中的丑陋块:
var myString =
'<div id="someId"> \
some content<br /> \
<a href="#someRef">someRefTxt</a> \
</div>';
这是另一个奇怪但有效的“技巧”1:
var myString = (function () {/*
<div id="someId">
some content<br />
<a href="#someRef">someRefTxt</a>
</div>
*/}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1];
外部编辑:jsfiddle
ES20xx支持使用template strings跨越多行字符串:
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 注意:在缩小/混淆您的代码后,这将丢失
【讨论】:
ECMAScript 6 (ES6) 引入了一种新的文字类型,即template literals。它们有很多特性,变量插值等等,但对于这个问题最重要的是,它们可以是多行的。
模板文字由反引号分隔:
var html = `
<div>
<span>Some HTML here</span>
</div>
`;
(注意:我不提倡在字符串中使用 HTML)
Browser support is OK,但您可以使用transpilers 更兼容。
Javascript 没有 here-document 语法。但是,您可以转义文字换行符,这很接近:
"foo \
bar"
【讨论】:
出于对互联网的热爱,请使用字符串连接并选择不使用 ES6 解决方案。 ES6 并非全面支持,就像 CSS3 和某些浏览器在适应 CSS3 运动方面很慢。使用普通的 JavaScript,您的最终用户会感谢您。
例子:
var str = "This world is neither flat nor round. "+
"Once was lost will be found";
【讨论】:
您必须使用连接运算符“+”。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<p id="demo"></p>
<script>
var str = "This "
+ "\n<br>is "
+ "\n<br>multiline "
+ "\n<br>string.";
document.getElementById("demo").innerHTML = str;
</script>
</body>
</html>
通过使用\n,您的源代码将如下所示 -
通过使用<br>,您的浏览器输出将如下所示 -
【讨论】:
使用脚本标签:
<script>...</script> 块添加到head 标记中;按原样获取多行文本...(注意文本编码: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>
【讨论】:
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 我不记得除了在 JS 中输入错误的 cmets 之外还有其他问题。没有问题的空间。
我通过输出一个div,将其隐藏,并在需要时通过jQuery调用div id来解决这个问题。
例如
<div id="UniqueID" style="display:none;">
Strings
On
Multiple
Lines
Here
</div>
然后当我需要获取字符串时,我只需要使用下面的 jQuery:
$('#UniqueID').html();
这会在多行上返回我的文本。如果我打电话给
alert($('#UniqueID').html());
我明白了:
【讨论】:
display:none 内容,这很可能是由于 JavaScript 样式前端的流行。 (例如,具有隐藏/显示功能的常见问题解答页面。)但您需要小心,因为 Google 表示,如果隐藏的内容似乎旨在人为抬高您的 SEO 排名,他们会惩罚您。
有多种方法可以实现这一点
1.斜线连接
var MultiLine= '1\
2\
3\
4\
5\
6\
7\
8\
9';
2。正则连接
var MultiLine = '1'
+'2'
+'3'
+'4'
+'5';
3.数组连接连接
var MultiLine = [
'1',
'2',
'3',
'4',
'5'
].join('');
性能方面,斜线连接(第一个)是最快的。
请参考this test case了解有关性能的更多详细信息
更新:
通过ES2015,我们可以利用其模板字符串功能。有了它,我们只需要使用反引号来创建多行字符串
例子:
`<h1>{{title}}</h1>
<h2>{{hero.name}} details!</h2>
<div><label>id: </label>{{hero.id}}</div>
<div><label>name: </label>{{hero.name}}</div>
`
【讨论】:
var string = "line1\ // comment, space or tabs here raise error
line2";
【讨论】:
ES6 允许您使用反引号在多行上指定一个字符串。它被称为模板文字。像这样:
var multilineString = `One line of text
second line of text
third line of text
fourth line of text`;
在 NodeJS 中使用反引号,Chrome、Firefox、Edge、Safari 和 Opera 都支持它。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
【讨论】:
javascript中的等价物是:
var text = `
This
Is
A
Multiline
String
`;
这是specification。请参阅此 page 底部的浏览器支持。这里也有一些examples。
【讨论】:
您可以使用TypeScript (JavaScript SuperSet),它支持多行字符串,并且可以无开销地转译回纯 JavaScript:
var templates = {
myString: `this is
a multiline
string`
}
alert(templates.myString);
如果您想使用纯 JavaScript 完成相同的操作:
var templates =
{
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(templates.myString)
注意 iPad/Safari 不支持'functionName.toString()'
如果你有很多遗留代码,你也可以在 TypeScript 中使用纯 JavaScript 变体(用于清理目的):
interface externTemplates
{
myString:string;
}
declare var templates:externTemplates;
alert(templates.myString)
您可以使用纯 JavaScript 变体中的多行字符串对象,将模板放入另一个文件(您可以将其合并到包中)。
试用 TypeScript【讨论】:
如果您愿意使用转义的换行符,可以很好地使用它们。 它看起来像一个带有页面边框的文档。
【讨论】:
2015 年更新:现在已经六年了:大多数人都使用模块加载器,并且主要的模块系统都有加载模板的方式。它不是内联的,但最常见的多行字符串类型是模板,模板通常应该远离 JS。
使用require.js 'text' plugin,在template.html
中使用多行模板var template = require('text!template.html')
浏览uses a 'brfs' module 以加载文本文件。这实际上会将您的模板构建到捆绑的 HTML 中。
var fs = require("fs");
var template = fs.readFileSync(template.html', 'utf8');
简单。
【讨论】:
这是一种相当经济的方法,至少就源代码而言:
function s() {
var args = [],index;
for (index = 0; index< arguments.length; index++) {
args.push (arguments [index]);
}
return args.join ("\n");
}
console.log (s (
"This is the first line",
"and this is the second",
"finally a third"
));
function s() {return arguments.join ("\n")}
如果“arguments”属性是一个合适的数组,当然会更好。
第二个版本可能会使用 "" 来处理您想要控制很长字符串中的换行符的情况。
【讨论】:
function s() { return Array.prototype.join.call(arguments, '\n'); }
如果你碰巧只在 Node 中运行,你可以使用 fs 模块从文件中读取多行字符串:
var diagram;
var fs = require('fs');
fs.readFile( __dirname + '/diagram.txt', function (err, data) {
if (err) {
throw err;
}
diagram = data.toString();
});
【讨论】:
这个库让它变得很漂亮:
https://github.com/sindresorhus/multiline
var str = '' +
'<!doctype html>' +
'<html>' +
' <body>' +
' <h1>❤ unicorns</h1>' +
' </body>' +
'</html>' +
'';
var str = multiline(function(){/*
<!doctype html>
<html>
<body>
<h1>❤ unicorns</h1>
</body>
</html>
*/});
【讨论】:
nodejs,在浏览器中使用一定要小心。
Function.prototype.String()。
你可以这样做...
var string = 'This is\n' +
'a multiline\n' +
'string';
【讨论】:
您可以使用+= 连接您的字符串,似乎没有人回答这个问题,这将是可读的,而且也很整洁......像这样
var hello = 'hello' +
'world' +
'blah';
也可以写成
var hello = 'hello';
hello += ' world';
hello += ' blah';
console.log(hello);
【讨论】:
我的扩展名为https://stackoverflow.com/a/15558082/80404。
它希望以/*! any multiline comment */ 的形式发表评论,其中符号!用于防止通过缩小删除(至少对于 YUI 压缩器)
Function.prototype.extractComment = function() {
var startComment = "/*!";
var endComment = "*/";
var str = this.toString();
var start = str.indexOf(startComment);
var end = str.lastIndexOf(endComment);
return str.slice(start + startComment.length, -(str.length - end));
};
例子:
var tmpl = function() { /*!
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
</ul>
</div>
*/}.extractComment();
【讨论】:
我找到了一个更优雅的解决方案,可能有点与主题无关,因为它使用 PHP,但我相信它对你的一些人来说会很有用和可爱*...
此 javascript 代码 应保留在脚本标签内
var html=<?php echo json_encode("
<div class=container>
<div class=area1>
xxx
</div>
<div class=area2>
".$someVar."
</div>
</div>
"); ?>
在您的 输出 html 中,您会看到类似
var html="\r\n\r\n\t\t\t<div class=container>\r\n\t\t\t\t<div class=area1>\r\n\t\t\t\t\txxx\r\n\t\t\t\t<\/div>\r\n\t\t\t\t<div class=area2>\r\n\t\t\t\t\t44\r\n\t\t\t\t<\/div>\r\n\t\t\t<\/div>\r\n\r\n\t\t";
并且等等!,它使您的文件中的代码具有可读性。
pD:此示例使用 json_encode() PHP 函数,但肯定有 ASP、Ruby 和 JSP 语言的等效函数。
pD:然而,这个解决方案也有他的局限性,其中之一是你不能在封装的代码中使用 javascript 变量。
【讨论】: