我正在使用模板字符串来生成一些文件,我喜欢为此目的的新f字符串的简洁性,以减少我之前的模板代码,如下所示:
template_a = "The current name is {name}"
names = ["foo", "bar"]
for name in names:
print (template_a.format(**locals()))
Run Code Online (Sandbox Code Playgroud)
现在我可以这样做,直接替换变量:
names = ["foo", "bar"]
for name in names:
print (f"The current name is {name}")
Run Code Online (Sandbox Code Playgroud)
但是,有时在其他地方定义模板是有意义的 - 在代码中更高,或从文件或其他东西导入.这意味着模板是一个带有格式标签的静态字符串.必须在字符串上发生一些事情,告诉解释器将字符串解释为新的f字符串,但我不知道是否有这样的事情.
有没有办法引入一个字符串并将其解释为f字符串以避免使用该.format(**locals())调用?
理想情况下,我希望能够像这样编码......(magic_fstring_function我不理解的部分在哪里进来):
template_a = f"The current name is {name}"
# OR [Ideal2] template_a = magic_fstring_function(open('template.txt').read())
names = ["foo", "bar"]
for name in names:
print (template_a)
Run Code Online (Sandbox Code Playgroud)
...使用此期望的输出(不读取文件两次):
The current name is foo
The current name is bar
Run Code Online (Sandbox Code Playgroud)
...但我得到的实际输出是:
The current …Run Code Online (Sandbox Code Playgroud) C#6中的字符串插值让我写:
decimal m = 42.0m;
string x = $"The value is {m}";
Run Code Online (Sandbox Code Playgroud)
但是,字符串格式化的一个非常常见的用例是指定用于格式化值的语言环境.假设我需要InvariantCulture用于上面的格式化操作,那是什么语法?
这个讨论表明我应该能够做到这一点:
string x = INV($"The value is {m}");
Run Code Online (Sandbox Code Playgroud)
其中INV定义为
public static string INV(IFormattable formattable)
{
return formattable.ToString(null, System.Globalization.CultureInfo.InvariantCulture);
}
Run Code Online (Sandbox Code Playgroud)
但是,这不起作用.它编译,但它启动时我的程序挂在cmd.exe中 - 好像我假设正在调用klr.exe,挂起(编译器错误?)
这是VS15 CTP 6中的ASP.NET 5控制台项目.
C#6为内插字符串文字带来了编译器支持,语法如下:
var person = new { Name = "Bob" };
string s = $"Hello, {person.Name}.";
Run Code Online (Sandbox Code Playgroud)
这对于短字符串很有用,但是如果要生成更长的字符串,必须在一行中指定它吗?
使用其他类型的字符串,您可以:
var multi1 = string.Format(@"Height: {0}
Width: {1}
Background: {2}",
height,
width,
background);
Run Code Online (Sandbox Code Playgroud)
要么:
var multi2 = string.Format(
"Height: {1}{0}" +
"Width: {2}{0}" +
"Background: {3}",
Environment.NewLine,
height,
width,
background);
Run Code Online (Sandbox Code Playgroud)
我无法找到一种方法来实现这一点,使用字符串插值,而不是只有一行:
var multi3 = $"Height: {height}{Environment.NewLine}Width: {width}{Environment.NewLine}Background: {background}";
Run Code Online (Sandbox Code Playgroud)
我意识到在这种情况下你可以用来\r\n代替Environment.NewLine(不太便携),或者把它拉到本地,但是有些情况下你不能将它减少到一行以下而不会失去语义强度.
是不是字符串插值不应该用于长字符串?
我们应该使用StringBuilder更长的字符串吗?
var multi4 = new StringBuilder()
.AppendFormat("Width: {0}", width).AppendLine()
.AppendFormat("Height: {0}", height).AppendLine()
.AppendFormat("Background: {0}", background).AppendLine()
.ToString();
Run Code Online (Sandbox Code Playgroud)
还是有更优雅的东西?
这是基本的例子
val name = "World" //> name : String = World
val message = s"Hello $name" //> message : String = Hello World
Run Code Online (Sandbox Code Playgroud)
我想知道是否有办法进行动态插值,例如以下(不编译,仅用于说明目的)
val name = "World" //> name : String = World
val template = "Hello $name" //> template : String = Hello $name
//just for illustration:
val message = s(template) //> doesn't compile (not found: value s)
Run Code Online (Sandbox Code Playgroud)
有没有办法"动态"评估像这样的字符串?(或者它本身是错误的/不可能的)
究竟是s什么?它不是def方法(显然它是一个方法StringContext),而不是一个对象(如果它是,它会抛出一个不同于我认为未找到的编译错误)
Scala有三个引用的字符串"""String\nString""",可以在字符串中使用特殊字符而不进行转义.Scala 2.10也添加raw"String\nString"了相同的用途.
如何raw""和""""""工作有什么区别?他们可以为同一串产生不同的输出吗?
我试图找出我的单元测试失败的原因(下面的第三个断言):
var date = new DateTime(2017, 1, 1, 1, 0, 0);
var formatted = "{countdown|" + date.ToString("o") + "}";
//Works
Assert.AreEqual(date.ToString("o"), $"{date:o}");
//Works
Assert.AreEqual(formatted, $"{{countdown|{date.ToString("o")}}}");
//This one fails
Assert.AreEqual(formatted, $"{{countdown|{date:o}}}");
Run Code Online (Sandbox Code Playgroud)
AFAIK,这应该可以正常工作,但看起来它没有正确传递格式化参数,它只显示为{countdown|o}代码.知道为什么会失败吗?
与问题相关:如何用Perl中的计算表达式替换?
在Perl中,有没有像Ruby这样的方法:
$a = 1;
print "#{$a + 1}";
Run Code Online (Sandbox Code Playgroud)
它可以打印出来2吗?
在Python中,编写它是很繁琐的:
print "foo is" + bar + '.'
Run Code Online (Sandbox Code Playgroud)
我可以在Python中做这样的事吗?
print "foo is #{bar}."
ruby python language-comparisons string-formatting string-interpolation
我不能让字符串插值工作.MS发现的最新消息是
http://blogs.msdn.com/b/csharpfaq/archive/2014/11/20/new-features-in-c-6.aspx
然而所有这一切都表示,目前没有工作.有人知道字符串插值是否进入VS 2015?有没有关于它的文件?你举个例子吗?
例如,这些格式都不起作用(编辑):
int i = 42;
var s = "\{i}"; // correction after jon's answer: this works!
var s = $"{i}"; // compiler error
var s = "{{i}}"; // no interpolation
Run Code Online (Sandbox Code Playgroud)
编辑关于VS 2015 CTP 6(20.4.2015)
最终版本是
var s = $"{i}"
Run Code Online (Sandbox Code Playgroud)
目前的Resharper版本ReSharper 9.1.20150408.155143也支持
在C#6中,新字符串插值的默认文化是什么?
我已经看到了关于Invariant和Current Culture的相互矛盾的报道.
我希望得到一个明确的答案,我会不停地指责Invariant.
c# ×5
c#-6.0 ×4
python ×2
scala ×2
string ×2
.net ×1
f-string ×1
multiline ×1
perl ×1
python-3.6 ×1
python-3.x ×1
roslyn ×1
ruby ×1
scala-2.10 ×1