C# How to add placement variable into a resource string - c#

This should be easy, but can't find anything to explain it.
Say I am writing something out on console.writeln like:
console.writeln("Jim is a {0} ", xmlscript);
Say I wanted to convert string `"Jim is.." to a resource string in a global resource.resx. It would be:
jimstring jim is a {0}
and I would refer to it in code as
console.writeln(Resources.jimstring)
How to I put the placement variable (xmlscript) (is this what they are called?) into the resource string in console.writeln?
Thanks,
Bob

As Jeff Johnson mentioned in his answer, it basically the exact same thing as the original Console.WriteLine(). The resource string is just a string. So you reference the resource file and do the format.
If you need it for something other than the Console you can use the String.Format():
var newString = String.Format(resources.jimstring, xmlscript);

Console.WriteLine(Resources.jimstring, xmlscript);
Console.WriteLine takes additional formatting arguments that will replace the {0} in your Resources.jimstring string.
More info here: http://msdn.microsoft.com/en-us/library/828t9b9h.aspx

Related

RegEx to replace string in C#

I'm really not great with RegEx in C#, never really used them but I have a long string that contains a lot of html that may contain numerous text parts like
src="Folder/Uploads/fd123051-532d-4804-a0fb-fd4ce6b70f7c/cd212dd7-7600-4b3f-a7d9-9a85c85a50ca.png"
or
src="Uploads/fd123051-532d-4804-a0fb-fd4ce6b70f7c/cd212dd7-7600-4b3f-a7d9-9a85c85a50ca.png"
I want to apply a reg ex over the string if it can be done in C# so it replaces the folder path so it will change any and all to be src = filename.extension
ie.
src="Uploads/fd123051-532d-4804-a0fb-fd4ce6b70f7c/cd212dd7-7600-4b3f-a7d9-9a85c85a50ca.png"
becomes
src="cd212dd7-7600-4b3f-a7d9-9a85c85a50ca.png"
Can anyone please help?
RegEx for your replace:
src="Uploads/fd123051-532d-4804-a0fb-fd4ce6b70f7c/cd212dd7-7600-4b3f-a7d9-9a85c85a50ca.png"
Will be:
F: src="(.+?)//(.+?)//(.+?).png" [You can check "Dot Matches All"]
R: src="$1/$2/$3.png" Or you can use instead of $1 , /1 /2 /3 etc.
You can use:
src = Path.GetFileName(src);
You need substring function that will take only the part which you want from string Please go here.
Get file name from path

how to make string returned by ResourceManager.GetString not verbatim

Okay, I have a string
string textToShow = "this\nrocks"
which when put in label in winforms window will then show
this
rocks
Which is the result I'd like to get. Now, instead of setting the textToShow in the code, I set it in the resource file. When I tried to get the value from resource file using
Properties.Resources.ResourceManager.GetString("textToShow");
the whole string instead will be treated as verbatim, showing
this\nrocks
when put in a label in a winforms window. This is not the result i'm looking for. What's the best way to store strings with special characters in resource file then? I can do string replace for every special characters, like
string.Replace(#"\n", "\n");
but then I need to replace every special characters whenever I call method ResourceManager.GetString, which I think is not the most elegant solution. If there is some ways to make string returned from method ResourceManager.GetString not verbatim, please do tell me.
Thanks
This was already answered here: StackOverflow: How to deal with newline
Basically you have two useful options:
Use shift + enter in the resource manager text editer to add a new line.
Or use String.Format() to replace {0} with \n on read.
The .Net 4.5 framework has the unescape functionality as shown here:
using System.Text.RegularExpressions;
Regex.Unescape(Properties.Resources.ResourceManager.GetString("textToShow"));
solves your issue. Now you can use \n and \u in the resource files.
On the resource editor type "this<shift+enter>rocks" as the resource value.

String Format descriptive text

Is it possible to add some descriptive text to a string format specifier?
Example:
string.Format ("{0:ForeName} is not at home", person.ForeName);
In the example ForeName is added as description.
The above syntax is obviously incorrect, but just to show the idea.
The reason I am asking, is because in my case the strings are in a resource file, so in the resource file you currently only see
{0} is not at home
in some cases it is hard to grasp what the context of {0} is.
EDIT:
In c# 6 string interpolation with the $ operator has been introduced, so string.Format is not needed anymore:
$"{person.ForeName} is not at home";
We usually put comments into our resources file e.g. {0} = Forename.
Then anybody who might be translating the string knows what {0} represents and can translate accordingly.
Also if you use ReSharper, you can enter the comment at the same time when you are adding your string to resources.
Phil Haack and Peli have written a couple of interesting blog posts about alternatives to the default string.format function. They might interest you.
Basically they allow you to use object properties inside the format string like this:
string s = NamedFormat("Hello {FullName} ({EmailAdrress})!", person);
You can the related blog posts here:
http://blog.dotnetwiki.org/2009/01/16/NamedFormatsPexTestimonium.aspx
http://haacked.com/archive/2009/01/14/named-formats-redux.aspx/
http://haacked.com/archive/2009/01/04/fun-with-named-formats-string-parsing-and-edge-cases.aspx/
Perhaps one of the solutions covered in those blog posts would suit your needs.
For strings your method should work, since strings will ignore any format specifiers. However you run the risk of accidentally using that for non-string types, in which case the string will either be translated as format codes or literally displayed:
string.Format ("{0:ForeName} is not at home", "Johnny");
//"Johnny is not at home"
string.Format ("{0:ForeName} will be home at {1:HomeTime}", "Johnny", DateTime.Today)
//Johnny will be home at 0o0eTi0e -- H, h, and m are DateTime format codes.
However since you're storing these in a resource file, I would instead use the "comment" field in the resource file - you could store a copy of the format string and add your descriptions there.
There is no built-in C# function for that. The best I can propose is to insert a comment (this will have no performance impact) :
string.Format ("{0"/*ForeName*/+"} is not at home", person.ForeName);
Personnaly, I don't find it readable, the best approch is to use a third-party tool as David Khaykin suggested in comment (see this answer)
IDEOne.com demo
Here is a somewhat naive implementation of StackOverflow's formatUnicorn method:
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Reflection;
public class Test
{
public static void Main()
{
string formatString = "{firstName} {lastName} is awesome.";
Console.WriteLine(formatString.FormatUnicorn(new {
firstName = "joe",
lastName = "blow"
}));
}
}
public static class StringExtensions {
public static string FormatUnicorn(this string str, object arguments) {
string output = str;
Type type = arguments.GetType();
foreach (PropertyInfo property in type.GetProperties())
{
Regex regex = new Regex(#"\{" + property.Name + #"\}");
output = regex.Replace(output, property.GetValue(arguments, null).ToString());
}
return output;
}
}
The biggest drawback here is the use of reflection, which can be slow. The other is that it doesn't allow for format specifiers.
A better approach might be to create a more complex regular expression that just strips out the comments.
string.Format ("{0} is not at home {1} ", person.ForeName, person.Something);
This shall print the ForeName instead of {0} and something in {1}. There is no way to as you said.
As of Visual Studio 2015 you can do this with Interpolated Strings (its a compiler trick, so it doesn't matter which version of the .net framework you target).
The code then looks something like this
string txt = $"{person.ForeName} is not at home {person.Something}";
Its not ideal if you want to put the strings into resource files for translation, but it oftern makes the code more readable and less error prone.

how to get a String with String.Format to execute?

I have a little chunk of code (see below) that is returning the string:
string.Format("{0}----{1}",3,"test 2");
so how do I get this to actually "Execute"? To run and do the format/replacement of {0} and {1}?
My Code snippet:
StringBuilder sb = new StringBuilder();
sb.Append("{0}----{1}\",");
sb.AppendFormat(ReturnParamValue(siDTO, "siDTO.SuggestionItemID,siDTO.Title"));
string sbStr = "=string.Format(\""+sb.ToString()+");";
yes, ReturnParamValue gives the actually value of the DTO.
Anyways, I've taken a look at the following (but it doesn't say how to execute it:
How to get String.Format not to parse {0}
Maybe, I just should put my code snippet in a method. But, what then?
Why are you including String.Format in the string itself?
If you're looking for a generic "let me evaluate this arbitrary expression I've built up in a string" then there isn't a simple answer.
If, instead, you're looking at how to provide the parameters to the string from a function call, then you've got yourself all twisted up and working too hard.
Try something like this, based on your original code:
string result
= string.Format(
"{0}----{1}",
ReturnParamValue(siDTO, "siDTO.SuggestionItemID,siDTO.Title"));
Though, this won't entirely work since your original code seems to be only providing a single value, and you have two values in your format string - the {0} will be replaced with the value from your function, and {1} left unchanged.
What output are you expecting?
Does your ReturnParamValue() function try to return both the label and the value in a single string? If it does, and if they're comma separated, then you could try this:
var value = ReturnParamValue(siDTO, "siDTO.SuggestionItemID,siDTO.Title"));
var pieces = string.Split(',');
string result
= string.Format( "{0}----{1}", pieces[0], pieces[1]);
Though this is seriously working too hard if ReturnParamValue() is a method you control.
Update Fri 6 August
Check out the declaration for string.Format() as shown on MSDN:
public static string Format(
string format,
params Object[] args
)
Unlike the special casing you might have seen in C for printf(), there's nothing special or unusual about the way string.Format() handles multiple parameters. The key is the params keyword, which asks the compiler to provide a little "syntactic sugar" where it combines the parameters into an array for you.
Key here is that the wrapping doesn't happen if you're already passing a single object[] - so if you wanted to, you could do something like this:
object[] parameters
= ReturnParamValues(siDTO, "siDTO.SuggestionItemID,siDTO.Title");
string result
= string.Format("{0}----{1}----{2}", parameters);
Though, if I saw something like this in any codebase I maintained, I'd be treating it as a code-smell and looking for a better way to solve the problem.
Just because it's possible doesn't mean it's advisable. YMMV, of course.
I don't think you can execute it. Java is not really a interpreted language.
You may make use of scripting languages (which can even embed in your Java app as I know, start from JDK6) for such purpose, like Groovy
You could use RegEx to parse the three parameters out of the string, and then pass them to a real, actual string.Format method :-)
It looks like what you want is something like this:
string sbStr = string.Format("{0}----{1}", siDTO.SuggestionItemID, siDTO.Title);
Maybe i didn't understand your question completely, but it sounds like you need to format a format-string. If that's true you could maybe try something like this:
int width = 5;
string format = String.Format("{{0,{0}}}----{{1,{0}}}", width);
string result = String.Format(format, "ab", "cd");
So the trick is simply to escape the { or } by using a double {{ or }}.

Reverse of String.Format? [duplicate]

This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
Parsing formatted string.
How can I use a String.Format format and transform its output to its inputs?
For example:
string formatString = "My name is {0}. I have {1} cow(s).";
string s = String.Format(formatString, "strager", 2);
// Call the magic method...
ICollection<string> parts = String.ReverseFormat(formatString, s);
// parts now contains "strager" and "2".
I know I can use regular expressions to do this, but I would like to use the same format string so I only need to maintain one line of code instead of two.
Here is some code from someone attempting a Scanf equivalent in C#:
http://www.codeproject.com/KB/recipes/csscanf.aspx
You'll have to implement it yourself, as there's nothing built in to do it for you.
To that end, I suggest you get the actual source code for the .Net string.format implmentation (actually, the relevant code is in StringBuilder.AppendFormat()). It's freely available, and it uses a state machine to walk the string in a very performant manner. You can mimic that code to also walk your formatted string and extract that data.
Note that it won't always be possible to go backwards. Sometimes the formatted string can have characters the match the format specifiers, making it difficult to impossible for the program to know what the original looked like. As I think about it, you might have better luck walking the original string to turn it into a regular expression, and then use that to do the match.
I'd also recommend renaming your method to InvertFormat(), because ReverseFormat sounds like you'd expect this output:
.)s(woc 2 evah .regarts si eman yM
I don't believe there's anything in-box to support this, but in C#, you can pass an array of objects directly to any method taking params-marked array parameters, such as String.Format(). Other than that, I don't believe there's some way for C# & the .NET Framework to know that string X was built from magic format string Y and undo the merge.
Therefore, the only thing I can think of is that you could format your code thusly:
object[] parts = {"strager", 2};
string s = String.Format(formatString, parts);
// Later on use parts, converting each member .ToString()
foreach (object p in parts)
{
Console.WriteLine(p.ToString());
}
Not ideal, and probably not quite what you're looking for, but I think it's the only way.

Categories

Resources