How to write C# regular expression pattern to match basic printf format-strings like "%5.2f"?
It should match the following criteria (conditional parts are in square brackets:
%[some numbers][.some 开发者_如何转开发numbers]d|f|s
notation d|f|s means that one of them has to be there.
Thanks & BR -Matti
This should do it:
string input = "Bloke %s drank %5.2f litres of water and ate %d bananas";
string pattern = @"%(\d+(\.\d+)?)?(d|f|s)";
foreach (Match m in Regex.Matches(input, pattern))
{
Console.WriteLine(m.Value);
}
I didn't use [dfs]
in my pattern since I planned to update it to use named groups. This is based on your earlier question about figuring out a replacement strategy for C-style format strings.
Here's an idea:
string input = "Bloke %s drank %5.2f litres of water and ate %d bananas";
string pattern = @"%(?<Number>\d+(\.\d+)?)?(?<Type>d|f|s)";
int count = 0;
string result = Regex.Replace(input, pattern, m =>
{
var number = m.Groups["Number"].Value;
var type = m.Groups["Type"].Value;
// now you can have custom logic to check the type appropriately
// check the types, format with the count for the current parameter
return String.Concat("{", count++, "}");
});
C#/.NET 2.0 approach:
private int formatCount { get; set; }
void Main()
{
string input = "Bloke %s drank %5.2f litres of water and ate %d bananas";
Console.WriteLine(FormatCStyleStrings(input));
}
private string FormatCStyleStrings(string input)
{
formatCount = 0; // reset count
string pattern = @"%(?<Number>\d+(\.\d+)?)?(?<Type>d|f|s)";
string result = Regex.Replace(input, pattern, FormatReplacement);
return result;
}
private string FormatReplacement(Match m)
{
string number = m.Groups["Number"].Value;
string type = m.Groups["Type"].Value;
// custom logic here, format as needed
return String.Concat("{", formatCount++, "}");
}
%(?:\d+)?(?:\.\d+)?[dfs]
Is the answer to your question, but I suspect you may have asked the wrong question, as printf
admits rather more than that.
Here is an expression matching all fields of format strings of printf/scanf functions.
(?<!%)(?:%%)*%([\-\+0\ \#])?(\d+|\*)?(\.\*|\.\d+)?([hLIw]|l{1,2}|I32|I64)?([cCdiouxXeEfgGaAnpsSZ])
It is based on Format Fields Specification. According to this specification %[flags][width][.precision][{h|l|ll|L|I|I32|I64|w}]type
match groups will contain: #1 - flags, #2 - width, #3 - precision, #4 - size prefix, #5 - type.
Taken from here.
精彩评论