Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在c#中执行替换标记的更好方法?_C#_Regex_Templating - Fatal编程技术网

在c#中执行替换标记的更好方法?

在c#中执行替换标记的更好方法?,c#,regex,templating,C#,Regex,Templating,我需要一个更好的方法来做到这一点: Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(textMessage.Trim(), "{birthday}", person.Birthday, RegexOptions.None), "{phone}", person.MobilePhone, RegexOptions.None), "{email}", person.Email, RegexOptions.No

我需要一个更好的方法来做到这一点:

Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(textMessage.Trim(), "{birthday}", person.Birthday, RegexOptions.None), "{phone}", person.MobilePhone, RegexOptions.None), "{email}", person.Email, RegexOptions.None), "{lastname}", person.LastName, RegexOptions.None), "{firstname}", person.FirstName, RegexOptions.None)

我更喜欢匹配,比如说,
{word}
,然后使用

然后很容易让字典(或开关或任何东西)提供替换输入(对于给定的“单词”)

还有其他优点,例如更好的运行时特性(
O(n)
vs
O(k*n)
),可以很好地扩展/允许分离替换数据,并且在其中一个替换包含
{}
内容时不会受到影响

快乐编码


我是从一个老项目中挖出来的。看起来这甚至“理解”了格式。YMMV

/// <summary>
/// Like string.Format but takes "{named}" identifiers with a Dictionary
/// of replacement values.
/// </summary>
/// <param name="format"></param>
/// <param name="replaces"></param>
/// <returns></returns>
public static string Format(string format, IDictionary<string,object> replaces) {
    if (format == null) throw new ArgumentNullException("format");
    if (replaces == null) throw new ArgumentNullException("replaces");
    return Regex.Replace(format, @"{(?<key>\w+)(?:[:](?<keyFormat>[^}]+))?}", (match) => {
        Object value;
        var key = match.Groups["key"].Value;
        var keyFormat = match.Groups["keyFormat"].Value;
        if (replaces.TryGetValue(key, out value)) {
            if (string.IsNullOrEmpty(keyFormat)) {
                return "" + value;
            } else {
                // format if applicable
                return string.Format("{0:" + keyFormat + "}", value);
            }
        } else {
            // don't replace not-found
            return match.Value;
        }
    });
}
//
///与string.Format类似,但使用字典获取“{named}”标识符
///重置价值的计算。
/// 
/// 
/// 
/// 
公共静态字符串格式(字符串格式,IDictionary替换){
如果(format==null)抛出新的ArgumentNullException(“format”);
如果(replaces==null)抛出新的ArgumentNullException(“replaces”);
返回Regex.Replace(格式,@“{(?\w+(:[:](?[^}]+))?}”,(匹配)=>{
目标价值;
var key=match.Groups[“key”].Value;
var keyFormat=match.Groups[“keyFormat”].Value;
if(替换.TryGetValue(键,输出值)){
if(string.IsNullOrEmpty(keyFormat)){
返回“”+值;
}否则{
//格式(如适用)
返回string.Format(“{0:”+keyFormat+“}”,value);
}
}否则{
//不替换未找到的
返回match.Value;
}
});
}
当然,以一种更简单的方式(从上面提取,YMMV x2):

var person=GetPerson();//我喜欢闭包
var res=Regex.Replace(输入,@“{(?\w+)}”,(匹配)=>{
开关(匹配组[“键”].值){
案例“生日”:返回人。生日;
// ....
默认值:返回“”;
}
});
IDictionary replacements=new Dictionary();
替换。添加(“{birth}”,person.birth);
替换。添加(“{phone}”,person.MobilePhone);
...
foreach(replacements.Keys中的字符串s){
Regex.Replace(textMessage,s,replacements[s],RegexOptions.None);
}

string.Format()?字符串的Replace()方法?更详细的信息?当“正则表达式”只是一个文本字符串时,为什么要费劲地使用Regex.Replace?正如其他人所观察到的,您还不如使用string自己的
Replace
方法。如果您必须使用Regex版本,则不必麻烦指定
RegexOptions.None
。这与不指定任何选项相同,使其成为纯粹的混乱。
/// <summary>
/// Like string.Format but takes "{named}" identifiers with a Dictionary
/// of replacement values.
/// </summary>
/// <param name="format"></param>
/// <param name="replaces"></param>
/// <returns></returns>
public static string Format(string format, IDictionary<string,object> replaces) {
    if (format == null) throw new ArgumentNullException("format");
    if (replaces == null) throw new ArgumentNullException("replaces");
    return Regex.Replace(format, @"{(?<key>\w+)(?:[:](?<keyFormat>[^}]+))?}", (match) => {
        Object value;
        var key = match.Groups["key"].Value;
        var keyFormat = match.Groups["keyFormat"].Value;
        if (replaces.TryGetValue(key, out value)) {
            if (string.IsNullOrEmpty(keyFormat)) {
                return "" + value;
            } else {
                // format if applicable
                return string.Format("{0:" + keyFormat + "}", value);
            }
        } else {
            // don't replace not-found
            return match.Value;
        }
    });
}
var person = GetPerson(); // I love closures
var res = Regex.Replace(input, @"{(?<key>\w+)}", (match) => {
    switch (match.Groups["key"].Value) {
        case "birthday": return person.Birthday;
        // ....
        default: return "";
    }
});
IDictionary<string, string> replacements = new Dictionary<string, string>();
replacements.Add("{birthday}", person.Birthday);
replacements.Add("{phone}", person.MobilePhone);
...

foreach (string s in replacements.Keys) {
    Regex.Replace(textMessage, s, replacements[s], RegexOptions.None);
}