如何在Ruby中生成多行字符串文字而不使用HERE-DOCUMENT语法? 问题摘要
我想尝试一下Ruby,因为我在Python中做了一些事情。在Python中,它有如何在Ruby中生成多行字符串文字而不使用HERE-DOCUMENT语法? 问题摘要,ruby,string,Ruby,String,我想尝试一下Ruby,因为我在Python中做了一些事情。在Python中,它有r”“”,这很好,因为它允许将原始字符串与代码对齐,并以更自然的方式连接它们,而不需要特殊的缩进。在Ruby中,当使用原始字符串时,必须使用清除文档中的缩进 要处理此处文档中的缩进问题,一种方法是对核心String类进行修补,添加一个实例方法String\undent: class String def undent indentation = slice(/^\s+/).length gsub(
r”“”
,这很好,因为它允许将原始字符串与代码对齐,并以更自然的方式连接它们,而不需要特殊的缩进。在Ruby中,当使用原始字符串时,必须使用清除文档中的缩进
要处理此处文档中的缩进问题,一种方法是对核心String
类进行修补,添加一个实例方法String\undent
:
class String
def undent
indentation = slice(/^\s+/).length
gsub(/^.{#{ indentation }}/, '')
end
end
然后您可以像这样重写代码:
x = <<-'EOT'.undent
\\\hline is a raw string
another one \\\hline and so on
EOT
x=撤消Ruby的转义语法
如果你希望完全避免遗传病,并且假设你的常见情况是一系列恰好由三个\
组成的情况,那么像下面这样的情况如何
class String
def raw
gsub('\\'*2) { '\\'*3 }
end
end
class Array
def raw(separator = $,)
map(&:raw).join(separator)
end
end
这引入了一组#raw
实例方法来补偿Ruby将引导反斜杠视为转义字符的做法
例子
示例a)
示例b)
示例c)
或者,如果事先设置了$,=''
,甚至可以取消前导空格:
示例d)
示例e)
或者,如果您事先设置了$,=''
:
示例f)
结果
对于六个示例a)到f)中的每一个,结果是:
\\\hline is a raw string another one \\\hline and so on
如果这是一个一次性的数据块,那么Ruby具有鲜为人知的数据文件句柄:
#!/bin/env ruby
puts DATA.read
__END__
Hi there, this is data
\\\\quad backslashes are no problem!\\\\
在magic\uuuuu END\uuuuu
之后,文件中剩余的任何内容都将被视为未转换的字符串数据,可以从名为data
的文件句柄中读取
因此,您的脚本可以如下所示:
#!/usr/local/bin/ruby -w
File.open('/home/me/rb_latex.tex','w') {|fp| fp.print DATA.read }
__END__
'\\'\hline \\\\\\ (6 of them) // some stuff follows. All should be raw string
<!DOCTYPE html>
\[ stuff \]
<html>
<head>
<title>title</title>
<style>
video {
width: 100% !important;
eight: auto !important;
}
</html> \"quotes\" (did you see this?)
\\\hline $\sin(x)$
</style>' //notice this ' is in the raw string!, ok!
\begin{tabular}{c}\\\hline '''''' (6 of them)
x\\\hline
\end{tabular}another '''one \\\hline and so on'
!/usr/local/bin/ruby-w
File.open('/home/me/rb_latex.tex','w'){| fp | fp.print DATA.read}
__结束__
“\\”\hline(其中6个)//下面是一些内容。所有内容都应该是原始字符串
\[材料\]
标题
录像带{
宽度:100%!重要;
八:自动!重要;
}
\“引号\”(你看到这个了吗?)
\\\hline$\sin(x)$
“//注意这个”在原始字符串中!好的!
\开始{tabular}{c}\\\hline''''>(其中6个)
x\\\hline
\结束{tabular}另一个“'one\\\hline等”
尽管如此,我还是很好奇:为什么你要费心把它作为一个中间Ruby脚本来生成,它唯一的任务就是把它写到另一个文件中?直接把输出写到目标文件不是更方便吗?感谢你的回答。我知道这个问题的答案,并使用了它。但是我看不出这个答案是怎么回事我的问题是什么?我试图避免同时使用EOT,并解释了原因。问题是EOT迫使人们以某种方式缩进Ruby源代码本身中的字符串。我不是说Latex代码写入外部文件后的缩进。我不明白heredocs是如何迫使你(水平)缩进的当您将字符串与String#undent
一起使用时,请以某种方式缩进字符串。因此,如果我正确理解了您的示例,您不仅试图避免(水平)缩进的限制,而且也不希望(垂直)缩进换行符在文本的前面或后面?根据您的示例和最新评论,我现在假设:1.您希望对字符串进行尽可能原始的编码;2.您的字符串经常包含一系列文本反斜杠,特别是正好包含三个反斜杠的序列;3.您不需要插值(→ 双引号不是一个选项);4.你不想要语法上的换行符或缩进(→ herdeocs不是一个选项)。这就是你的要求吗?再次感谢。我一直在测试它。但我担心它不起作用。这个想法是它应该像HERE-DOCUMENT一样工作,但是有很好的语法%q{}为了更方便地格式化ruby源代码中的字符串。也就是说,文件中的任何内容都应按原样写入文件,不管它是什么。您的解析器没有处理所有情况。我将更新我的问题并添加一个示例输入供您尝试。写入文件后,文件中的输出应与原始str完全相同感谢你的最新更新和测试用例,但考虑到你的一系列要求,我将不得不通过这一测试。感谢你的回答。但这不是我想要的。我需要能够在代码中动态生成小片段的原始字符串,因为我可以更容易地在它们之间插入不同的字符串nt值基于一些其他逻辑来动态生成代码。这样做更容易,而且当我可以让原始字符串与代码本身一起流动时,代码也更容易阅读,而不是在不同的位置或必须打破代码缩进才能使用它。我现在可以用Python的r”“”
来做到这一点,我只是想,如果我能用Ruby做同样的事情。
import os
os.chdir("/home/me")
my_file = open("py_latex.tex", 'w')
x =r"""\\'\hline \\\\\\ (6 of them) // some stuff follows. All should be raw string
<!DOCTYPE html>
\[ stuff \]
<html>
<head>
<title>title</title>
<style>
video {
width: 100% !important;
eight: auto !important;
}
</html> \"quotes\" (did you see this?)
\\\hline $\sin(x)$
</style>' //notice this ' is in the raw string!, ok!
\begin{tabular}{c}\\\hline '''''' (6 of them)
x\\\hline
\end{tabular}}"""+r"""{another '''one \\\hline and so on'"""
my_file.write(x)
my_file.close()
class String
def undent
indentation = slice(/^\s+/).length
gsub(/^.{#{ indentation }}/, '')
end
end
x = <<-'EOT'.undent
\\\hline is a raw string
another one \\\hline and so on
EOT
class String
def raw
gsub('\\'*2) { '\\'*3 }
end
end
class Array
def raw(separator = $,)
map(&:raw).join(separator)
end
end
x = '\\\hline is a raw string'.raw + ' another one \\\hline and so on'.raw
x = %q{\\\hline is a raw string}.raw + %q{ another one \\\hline and so on}.raw
x = ['\\\hline is a raw string', ' another one \\\hline and so on'].raw
x = ['\\\hline is a raw string', 'another one \\\hline and so on'].raw
x = [%q{\\\hline is a raw string}, %q{ another one \\\hline and so on}].raw
x = [%q{\\\hline is a raw string}, %q{another one \\\hline and so on}].raw
\\\hline is a raw string another one \\\hline and so on
#!/bin/env ruby
puts DATA.read
__END__
Hi there, this is data
\\\\quad backslashes are no problem!\\\\
#!/usr/local/bin/ruby -w
File.open('/home/me/rb_latex.tex','w') {|fp| fp.print DATA.read }
__END__
'\\'\hline \\\\\\ (6 of them) // some stuff follows. All should be raw string
<!DOCTYPE html>
\[ stuff \]
<html>
<head>
<title>title</title>
<style>
video {
width: 100% !important;
eight: auto !important;
}
</html> \"quotes\" (did you see this?)
\\\hline $\sin(x)$
</style>' //notice this ' is in the raw string!, ok!
\begin{tabular}{c}\\\hline '''''' (6 of them)
x\\\hline
\end{tabular}another '''one \\\hline and so on'
my_file = File.open("/tmp/rb_latex.tex", 'w')
x = <<'EOT'
\\'\hline \\\\\\ (6 of them) // some stuff follows. All should be raw string
<!DOCTYPE html>
\[ stuff \]
<html>
<head>
<title>title</title>
<style>
video {
width: 100% !important;
eight: auto !important;
}
</html> \"quotes\" (did you see this?)
\\\hline $\sin(x)$
</style>' //notice this ' is in the raw string!, ok!
\begin{tabular}{c}\\\hline '''''' (6 of them)
x\\\hline
\end{tabular}}"""+r"""{another '''one \\\hline and so on'"""
EOT
my_file.write(x)
my_file.close()
cat /tmp/rb_latex.tex
\\'\hline \\\\\\ (6 of them) // some stuff follows. All should be raw string
<!DOCTYPE html>
\[ stuff \]
<html>
<head>
<title>title</title>
<style>
video {
width: 100% !important;
eight: auto !important;
}
</html> \"quotes\" (did you see this?)
\\\hline $\sin(x)$
</style>' //notice this ' is in the raw string!, ok!
\begin{tabular}{c}\\\hline '''''' (6 of them)
x\\\hline
\end{tabular}}"""+r"""{another '''one \\\hline and so on'"""