反转格式字符串并确定正确结果
Reverse format string and determinate correct result
我必须反转格式字符串以提取 "Email" 并确定正确的布尔结果。
string input = "The Email field is required.";
string required = "The {0} field is required.";
string date = "The {0} field is not a valid date.";
bool isRequired = false;
bool isDate = false;
string extractedField;
我的期望是让值 "Email" 变为 "extractedField" 并且 "isRequired" 变为 true
更新:
对不起,如果我在解释自己时过于笼统。为了更好地阐明我的意图,我创建了一个 fiddle https://dotnetfiddle.net/cjPAo1
我相信我理解您的 query.You 想要检查当前消息与哪个 "expression" 匹配,并根据它,将适当的标志设置为 true。同时检索有问题的 'field'。
实现它的一种方法是
更新
根据您的评论,已更新代码以支持多个字段。
string input = "Age should be between 1 and 99.";
string required = "The {0} field is required.";
string date = "The {0} field is not a valid date.";
string range = "{0} should be between {1} and {2}.";
bool isRequired = false;
bool isDate = false;
bool isRange = false;
string extractedField;
var possibilities = new []
{
new KeyValuePair<string,Action>(ToRegex(required), ()=>((Action)(() => { isRequired = true;}))()),
new KeyValuePair<string,Action>(ToRegex(date), ()=>((Action)(() => { isDate = true;}))()),
new KeyValuePair<string,Action>(ToRegex(range), ()=>((Action)(() => { isRange = true;}))())
};
var result = possibilities
.Where(x=>Regex.Match(input,x.Key).Success)
.Select(x=> new KeyValuePair<IEnumerable<string>,Action>(
Regex.Match(input,x.Key).Groups.Cast<Group>().Where(c=>c.Name.StartsWith("Field")).Select(c=>c.Value),
x.Value)).First();
var fields = result.Key;
result.Value();
Console.WriteLine($"{nameof(extractedField)}={string.Join(",",fields)},{Environment.NewLine}{nameof(isRequired)}={isRequired},{Environment.NewLine}{nameof(isDate)}={isDate}");
其中 ToRegex 定义为
public string ToRegex(string value)
{
var result = new List<string>();
foreach(var item in value.Split(' '))
{
if(Regex.Match(item,@"{(?<Value>\d*)}").Success)
{
var match = Regex.Match(item,@"{(?<Value>\d*)}");
result.Add(Regex.Replace(item,@"{(?<Value>\d*)}",$"(?<Field{match.Groups["Value"].Value}>\S*)"));
continue;
}
result.Add(item);
};
return string.Join(" ",result);
}
以上代码使用 Regex 找到合适的匹配项。
示例输出
extractedField=Age,1,99,
isRequired=False,
isDate=False
更新
根据您的评论,要支持多个词,您可以使用以下内容。
public string ToRegex(string value)
{
var result = new List<string>();
foreach(var item in value.Split(' '))
{
if(Regex.Match(item,@"{(?<Value>\d*)}").Success)
{
var match = Regex.Match(item,@"{(?<Value>\d*)}");
result.Add(Regex.Replace(item,@"{(?<Value>\d*)}",$"(?<Field{match.Groups["Value"].Value}>[\S ]*)"));
continue;
}
result.Add(item);
};
return string.Join(" ",result);
}
尝试以下操作:
class Program
{
static void Main(string[] args)
{
string[] inputs = {
"The Email field is required.",
"The Username field is required.",
"The InsertDate field is not a valid date.",
"Age should be between 1 and 99."
};
Type type;
foreach (string input in inputs)
{
string word = ExtractFieldAndDeterminateType(input, out type);
Console.WriteLine(word);
}
Console.ReadLine();
}
public static string ExtractFieldAndDeterminateType(string input, out Type type)
{
string[] words = input.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
int index = 0;
if (words[0] == "The") index = 1;
string word = words[index];
switch (word)
{
case "Email" :
type = typeof(string);
break;
case "Username":
type = typeof(string);
break;
case "InsertDate":
type = typeof(DateTime);
break;
case "Age":
type = typeof(int);
break;
default:
type = (Type)Type.Missing;
break;
}
return word;
}
}
使用Regex.Match
函数ExtractFieldAndDeterminateType
可以写成:
public static string ExtractFieldAndDeterminateType(string input, out Type type)
{
var extractedField = "";
string required = "The (.*) field is (.*).";
//string date = "The (.*) field is not a (.*)."; => Not needed
string range = "(.*)(?= should be between)";
type = Type.Unknown;
var match = Regex.Match(input, required);
if (match.Success)
{
extractedField = match.Groups[1].Value;
switch (match.Groups[2].Value)
{
case "required":
type = Type.Error;
break;
case "not a valid date":
type = Type.Date;
break;
}
}
else if ((match = Regex.Match(input, range)).Success)
{
extractedField = match.Groups[1].Value;
type = Type.Range;
}
else
{
//Nothing
}
return extractedField;
}
OP测试数据输出:
Field is: Email and Type is: Error
Field is: Username and Type is: Error
Field is: InsertDate and Type is: Date
Field is: Age and Type is: Range
已编辑: 已将示例代码添加到 fiddle Link to fiddle
我必须反转格式字符串以提取 "Email" 并确定正确的布尔结果。
string input = "The Email field is required.";
string required = "The {0} field is required.";
string date = "The {0} field is not a valid date.";
bool isRequired = false;
bool isDate = false;
string extractedField;
我的期望是让值 "Email" 变为 "extractedField" 并且 "isRequired" 变为 true
更新: 对不起,如果我在解释自己时过于笼统。为了更好地阐明我的意图,我创建了一个 fiddle https://dotnetfiddle.net/cjPAo1
我相信我理解您的 query.You 想要检查当前消息与哪个 "expression" 匹配,并根据它,将适当的标志设置为 true。同时检索有问题的 'field'。
实现它的一种方法是
更新
根据您的评论,已更新代码以支持多个字段。
string input = "Age should be between 1 and 99.";
string required = "The {0} field is required.";
string date = "The {0} field is not a valid date.";
string range = "{0} should be between {1} and {2}.";
bool isRequired = false;
bool isDate = false;
bool isRange = false;
string extractedField;
var possibilities = new []
{
new KeyValuePair<string,Action>(ToRegex(required), ()=>((Action)(() => { isRequired = true;}))()),
new KeyValuePair<string,Action>(ToRegex(date), ()=>((Action)(() => { isDate = true;}))()),
new KeyValuePair<string,Action>(ToRegex(range), ()=>((Action)(() => { isRange = true;}))())
};
var result = possibilities
.Where(x=>Regex.Match(input,x.Key).Success)
.Select(x=> new KeyValuePair<IEnumerable<string>,Action>(
Regex.Match(input,x.Key).Groups.Cast<Group>().Where(c=>c.Name.StartsWith("Field")).Select(c=>c.Value),
x.Value)).First();
var fields = result.Key;
result.Value();
Console.WriteLine($"{nameof(extractedField)}={string.Join(",",fields)},{Environment.NewLine}{nameof(isRequired)}={isRequired},{Environment.NewLine}{nameof(isDate)}={isDate}");
其中 ToRegex 定义为
public string ToRegex(string value)
{
var result = new List<string>();
foreach(var item in value.Split(' '))
{
if(Regex.Match(item,@"{(?<Value>\d*)}").Success)
{
var match = Regex.Match(item,@"{(?<Value>\d*)}");
result.Add(Regex.Replace(item,@"{(?<Value>\d*)}",$"(?<Field{match.Groups["Value"].Value}>\S*)"));
continue;
}
result.Add(item);
};
return string.Join(" ",result);
}
以上代码使用 Regex 找到合适的匹配项。
示例输出
extractedField=Age,1,99,
isRequired=False,
isDate=False
更新
根据您的评论,要支持多个词,您可以使用以下内容。
public string ToRegex(string value)
{
var result = new List<string>();
foreach(var item in value.Split(' '))
{
if(Regex.Match(item,@"{(?<Value>\d*)}").Success)
{
var match = Regex.Match(item,@"{(?<Value>\d*)}");
result.Add(Regex.Replace(item,@"{(?<Value>\d*)}",$"(?<Field{match.Groups["Value"].Value}>[\S ]*)"));
continue;
}
result.Add(item);
};
return string.Join(" ",result);
}
尝试以下操作:
class Program
{
static void Main(string[] args)
{
string[] inputs = {
"The Email field is required.",
"The Username field is required.",
"The InsertDate field is not a valid date.",
"Age should be between 1 and 99."
};
Type type;
foreach (string input in inputs)
{
string word = ExtractFieldAndDeterminateType(input, out type);
Console.WriteLine(word);
}
Console.ReadLine();
}
public static string ExtractFieldAndDeterminateType(string input, out Type type)
{
string[] words = input.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
int index = 0;
if (words[0] == "The") index = 1;
string word = words[index];
switch (word)
{
case "Email" :
type = typeof(string);
break;
case "Username":
type = typeof(string);
break;
case "InsertDate":
type = typeof(DateTime);
break;
case "Age":
type = typeof(int);
break;
default:
type = (Type)Type.Missing;
break;
}
return word;
}
}
使用Regex.Match
函数ExtractFieldAndDeterminateType
可以写成:
public static string ExtractFieldAndDeterminateType(string input, out Type type)
{
var extractedField = "";
string required = "The (.*) field is (.*).";
//string date = "The (.*) field is not a (.*)."; => Not needed
string range = "(.*)(?= should be between)";
type = Type.Unknown;
var match = Regex.Match(input, required);
if (match.Success)
{
extractedField = match.Groups[1].Value;
switch (match.Groups[2].Value)
{
case "required":
type = Type.Error;
break;
case "not a valid date":
type = Type.Date;
break;
}
}
else if ((match = Regex.Match(input, range)).Success)
{
extractedField = match.Groups[1].Value;
type = Type.Range;
}
else
{
//Nothing
}
return extractedField;
}
OP测试数据输出:
Field is: Email and Type is: Error
Field is: Username and Type is: Error
Field is: InsertDate and Type is: Date
Field is: Age and Type is: Range
已编辑: 已将示例代码添加到 fiddle Link to fiddle