@@ -15,10 +15,8 @@ internal static class EngineAlgorithim
1515 {
1616 private static readonly ConcurrentDictionary < Type , PropertyInfo [ ] > PropertyCache = new ConcurrentDictionary < Type , PropertyInfo [ ] > ( ) ;
1717
18- private static readonly Regex IfConditionRegex = new Regex ( @"{{\s*#if\s*\(\s*(?<param>\w+)\s*(?<operator>==|!=|>=|<=|>|<)\s*(?<value>[^)]+)\s*\)\s*}}(?<code>[\s\S]*?)(?:{{\s*#else\s*}}(?<else>[\s\S]*?))?{{\s*#endif\s*}}" , RegexOptions . IgnoreCase | RegexOptions . Compiled ) ;
19-
20- private static readonly Regex LoopBlockRegex = new Regex ( @"{{\s*#foreach\s*\(\s*(\w+)\s*\)\s*\}\}([\s\S]*?)\{\{\s*#endforeach\s*}}" , RegexOptions . IgnoreCase | RegexOptions . Compiled ) ;
21-
18+ private static readonly Regex IfConditionRegex = new Regex ( @"{{\s*#\s*if\s*\(\s*(?<param>\w+)\s*(?<operator>==|!=|>=|<=|>|<)\s*(?<value>[^)]+?)\s*\)\s*}}(?<code>[\s\S]*?)(?:{{\s*#\s*else\s*}}(?<else>[\s\S]*?))?{{\s*#\s*endif\s*}}" , RegexOptions . IgnoreCase | RegexOptions . Compiled ) ;
19+ private static readonly Regex LoopBlockRegex = new Regex ( @"{{\s*#\s*foreach\s*\(\s*(\w+)\s*\)\s*\}\}([\s\S]*?)\{\{\s*#\s*endforeach\s*}}" , RegexOptions . IgnoreCase | RegexOptions . Compiled ) ;
2220 private static readonly Regex DirectParamRegex = new Regex ( @"{{(.+?)}}" , RegexOptions . IgnoreCase | RegexOptions . Compiled ) ;
2321
2422 public static string GenerateFromTemplate < T > ( T record , EngineRunnerTemplate template , Dictionary < string , object > parameterKeyValues = null , TemplateMapperOptions options = null ) where T : new ( )
@@ -33,7 +31,7 @@ internal static class EngineAlgorithim
3331 {
3432 if ( ! propMap . TryGetValue ( ifCondition . IfPropertyName , out ExtractedObjProperty property ) )
3533 {
36- result . Replace ( ifCondition . ReplaceRef , "[IF-CONDITION EXCEPTION]: unrecognized property: [" + ifCondition . IfPropertyName + "]" ) ;
34+ result . ReplaceFirstOccurrence ( ifCondition . ReplaceRef , "[IF-CONDITION EXCEPTION]: unrecognized property: [" + ifCondition . IfPropertyName + "]" ) ;
3735 continue ;
3836 }
3937
@@ -55,15 +53,15 @@ internal static class EngineAlgorithim
5553 replacement = string . Empty ;
5654 }
5755
58- result . Replace ( ifCondition . ReplaceRef , replacement ) ;
56+ result . ReplaceFirstOccurrence ( ifCondition . ReplaceRef , replacement ) ;
5957 }
6058
6159 // ---- Object Loops ----
6260 foreach ( ReplaceObjLoopCode objLoop in template . ReplaceObjLoopCodes )
6361 {
6462 if ( ! propMap . TryGetValue ( objLoop . TargetObjectName , out ExtractedObjProperty targetObj ) || ! ( targetObj . OriginalValue is IEnumerable enumerable ) )
6563 {
66- result . Replace ( objLoop . ReplaceRef , string . Empty ) ;
64+ result . ReplaceFirstOccurrence ( objLoop . ReplaceRef , string . Empty ) ;
6765 continue ;
6866 }
6967
@@ -87,31 +85,32 @@ internal static class EngineAlgorithim
8785 Type = row . GetType ( ) ,
8886 OriginalValue = row
8987 } ;
90- activeRow . Replace ( objLoopCode . ReplaceRef , tempProp . GetPropertyDisplayString ( objLoopCode . GetFormattingCommand ( ) , options ) ) ;
88+ activeRow . ReplaceFirstOccurrence ( objLoopCode . ReplaceRef , tempProp . GetPropertyDisplayString ( objLoopCode . GetFormattingCommand ( ) , options ) ) ;
9189 }
9290 else
9391 {
9492 if ( rowMap . TryGetValue ( propName , out ExtractedObjProperty p ) )
95- activeRow . Replace ( objLoopCode . ReplaceRef , p . GetPropertyDisplayString ( objLoopCode . GetFormattingCommand ( ) , options ) ) ;
93+ activeRow . ReplaceFirstOccurrence ( objLoopCode . ReplaceRef , p . GetPropertyDisplayString ( objLoopCode . GetFormattingCommand ( ) , options ) ) ;
9694 else
97- activeRow . Replace ( objLoopCode . ReplaceRef , objLoopCode . ReplaceCommand ) ;
95+ activeRow . ReplaceFirstOccurrence ( objLoopCode . ReplaceRef , objLoopCode . ReplaceCommand ) ;
9896 }
9997 }
10098
10199 loopResult . Append ( activeRow ) ;
102100 }
103101
104- result . Replace ( objLoop . ReplaceRef , loopResult . ToString ( ) ) ;
102+ result . ReplaceFirstOccurrence ( objLoop . ReplaceRef , loopResult . ToString ( ) ) ;
105103 }
106104
107105 // ---- Direct Replacements ----
108106 foreach ( ReplaceCode replaceCode in template . ReplaceCodes )
109107 {
110108 if ( propMap . TryGetValue ( replaceCode . GetTargetPropertyName ( ) , out ExtractedObjProperty property ) )
111- result . Replace ( replaceCode . ReplaceRef , property . GetPropertyDisplayString ( replaceCode . GetFormattingCommand ( ) , options ) ) ;
109+ result . ReplaceFirstOccurrence ( replaceCode . ReplaceRef , property . GetPropertyDisplayString ( replaceCode . GetFormattingCommand ( ) , options ) ) ;
112110 else
113- result . Replace ( replaceCode . ReplaceRef , "{{ " + replaceCode . ReplaceCommand + " }}" ) ;
111+ result . ReplaceFirstOccurrence ( replaceCode . ReplaceRef , "{{ " + replaceCode . ReplaceCommand + " }}" ) ;
114112 }
113+
115114 return result . ToString ( ) ;
116115 }
117116
0 commit comments