@@ -28,13 +28,13 @@ public class ExpressionEvaluator
28
28
{
29
29
#region Regex declarations
30
30
31
- private static readonly string diactitics = "áàâãåǎăāąæéèêëěēĕėęěìíîïīĭįijóôõöōŏőøðœùúûüǔũūŭůűųýþÿŷıćĉċčçďđĝğġģĥħĵķĺļľŀłńņňŋñŕŗřśŝşšţťŧŵźżžÁÀÂÃÅǍĂĀĄÆÉÈÊËĚĒĔĖĘĚÌÍÎÏĪĬĮIJÓÔÕÖŌŎŐØÐŒÙÚÛÜǓŨŪŬŮŰŲÝÞŸŶIĆĈĊČÇĎĐĜĞĠĢĤĦĴĶĹĻĽĿŁŃŅŇŊÑŔŖŘŚŜŞŠŢŤŦŴŹŻŽß" ;
32
- private static readonly string diactiticsKeywordsRegexPattern = "a-zA-Z_" + diactitics ;
31
+ private const string diactitics = "áàâãåǎăāąæéèêëěēĕėęěìíîïīĭįijóôõöōŏőøðœùúûüǔũūŭůűųýþÿŷıćĉċčçďđĝğġģĥħĵķĺļľŀłńņňŋñŕŗřśŝşšţťŧŵźżžÁÀÂÃÅǍĂĀĄÆÉÈÊËĚĒĔĖĘĚÌÍÎÏĪĬĮIJÓÔÕÖŌŎŐØÐŒÙÚÛÜǓŨŪŬŮŰŲÝÞŸŶIĆĈĊČÇĎĐĜĞĠĢĤĦĴĶĹĻĽĿŁŃŅŇŊÑŔŖŘŚŜŞŠŢŤŦŴŹŻŽß" ;
32
+ private const string diactiticsKeywordsRegexPattern = "a-zA-Z_" + diactitics ;
33
33
34
34
private static readonly Regex varOrFunctionRegEx = new Regex ( $@ "^((?<sign>[+-])|(?<prefixOperator>[+][+]|--)|(?<inObject>(?<nullConditional>[?])?\.)?)(?<name>[{ diactiticsKeywordsRegexPattern } ][{ diactiticsKeywordsRegexPattern } 0-9]*)\s*((?<assignationOperator>(?<assignmentPrefix>[+\-*/%&|^]|<<|>>)?=(?![=>]))|(?<postfixOperator>([+][+]|--)(?![{ diactiticsKeywordsRegexPattern } 0-9]))|((?<isgeneric>[<](?>[^<>]+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?(?<isfunction>[(])?))", RegexOptions . IgnoreCase | RegexOptions . Compiled ) ;
35
35
36
- private readonly string numberRegexPattern = @"^(?<sign>[+-])?([0-9][0-9_{1}]*[0-9]|\d)(?<hasdecimal>{0}?([0-9][0-9_]*[0-9]|\d)(e[+-]?([0-9][0-9_]*[0-9]|\d))?)?(?<type>ul|[fdulm])?" ;
37
- private Regex numberRegex = null ;
36
+ private const string numberRegexOrigPattern = @"^(?<sign>[+-])?([0-9][0-9_{1}]*[0-9]|\d)(?<hasdecimal>{0}?([0-9][0-9_]*[0-9]|\d)(e[+-]?([0-9][0-9_]*[0-9]|\d))?)?(?<type>ul|[fdulm])?" ;
37
+ private string numberRegexPattern = null ;
38
38
39
39
private static readonly Regex otherBasesNumberRegex = new Regex ( @"^(?<sign>[+-])?(?<value>0(?<type>x)([0-9a-f][0-9a-f_]*[0-9a-f]|[0-9a-f])|0(?<type>b)([01][01_]*[01]|[01]))" , RegexOptions . IgnoreCase ) ;
40
40
private static readonly Regex stringBeginningRegex = new Regex ( "^(?<interpolated>[$])?(?<escaped>[@])?[\" ]" ) ;
@@ -57,18 +57,15 @@ public class ExpressionEvaluator
57
57
58
58
// Depending on OptionInlineNamespacesEvaluationActive. Initialized in constructor
59
59
private string InstanceCreationWithNewKeywordRegexPattern { get { return $@ "^new\s+(?<name>[{ diactiticsKeywordsRegexPattern } ][{ diactiticsKeywordsRegexPattern } 0-9{ ( OptionInlineNamespacesEvaluationActive ? @"\." : string . Empty ) } ]*)\s*(?<isgeneric>[<](?>[^<>]+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?\s*((?<isfunction>[(])|(?<isArray>\[)|(?<isInit>[{{]))?"; } }
60
- private Regex instanceCreationWithNewKeywordRegex = null ;
61
60
private string CastRegexPattern { get { return $@ "^\(\s*(?<typeName>[{ diactiticsKeywordsRegexPattern } ][{ diactiticsKeywordsRegexPattern } 0-9{ ( OptionInlineNamespacesEvaluationActive ? @"\." : string . Empty ) } \[\]<>]*[?]?)\s*\)"; } }
62
- private Regex castRegex = null ;
63
61
64
- private static readonly string primaryTypesRegexPattern = @"(?<=^|[^" + diactiticsKeywordsRegexPattern + @"])(?<primaryType>object|string|bool[?]?|byte[?]?|char[?]?|decimal[?]?|double[?]?|short[?]?|int[?]?|long[?]?|sbyte[?]?|float[?]?|ushort[?]?|uint[?]?|ulong[?]?|void)(?=[^a-zA-Z_]|$)" ;
65
- private Regex primaryTypesRegex = new Regex ( primaryTypesRegexPattern ) ;
62
+ private const string primaryTypesRegexPattern = @"(?<=^|[^" + diactiticsKeywordsRegexPattern + @"])(?<primaryType>object|string|bool[?]?|byte[?]?|char[?]?|decimal[?]?|double[?]?|short[?]?|int[?]?|long[?]?|sbyte[?]?|float[?]?|ushort[?]?|uint[?]?|ulong[?]?|void)(?=[^a-zA-Z_]|$)" ;
66
63
67
64
// To remove comments in scripts based on https://stackoverflow.com/questions/3524317/regex-to-strip-line-comments-from-c-sharp/3524689#3524689
68
- private static readonly string blockComments = @"/\*(.*?)\*/" ;
69
- private static readonly string lineComments = @"//[^\r\n]*" ;
70
- private static readonly string stringsIgnore = @"""((\\[^\n]|[^""\n])*)""" ;
71
- private static readonly string verbatimStringsIgnore = @"@(""[^""]*"")+" ;
65
+ private const string blockComments = @"/\*(.*?)\*/" ;
66
+ private const string lineComments = @"//[^\r\n]*" ;
67
+ private const string stringsIgnore = @"""((\\[^\n]|[^""\n])*)""" ;
68
+ private const string verbatimStringsIgnore = @"@(""[^""]*"")+" ;
72
69
private static readonly Regex removeCommentsRegex = new Regex ( $ "{ blockComments } |{ lineComments } |{ stringsIgnore } |{ verbatimStringsIgnore } ", RegexOptions . Singleline ) ;
73
70
private static readonly Regex newLineCharsRegex = new Regex ( @"\r\n|\r|\n" ) ;
74
71
@@ -519,8 +516,6 @@ public bool OptionCaseSensitiveEvaluationActive
519
516
simpleDoubleMathFuncsDictionary = new Dictionary < string , Func < double , double > > ( simpleDoubleMathFuncsDictionary , StringComparerForCasing ) ;
520
517
doubleDoubleMathFuncsDictionary = new Dictionary < string , Func < double , double , double > > ( doubleDoubleMathFuncsDictionary , StringComparerForCasing ) ;
521
518
complexStandardFuncsDictionary = new Dictionary < string , Func < ExpressionEvaluator , List < string > , object > > ( complexStandardFuncsDictionary , StringComparerForCasing ) ;
522
- instanceCreationWithNewKeywordRegex = new Regex ( InstanceCreationWithNewKeywordRegexPattern , ( optionCaseSensitiveEvaluationActive ? RegexOptions . None : RegexOptions . IgnoreCase ) ) ;
523
- primaryTypesRegex = new Regex ( primaryTypesRegexPattern , ( optionCaseSensitiveEvaluationActive ? RegexOptions . None : RegexOptions . IgnoreCase ) ) ;
524
519
}
525
520
}
526
521
@@ -577,7 +572,9 @@ public string OptionNumberParsingDecimalSeparator
577
572
optionNumberParsingDecimalSeparator = value ?? "." ;
578
573
CultureInfoForNumberParsing . NumberFormat . NumberDecimalSeparator = optionNumberParsingDecimalSeparator ;
579
574
580
- numberRegex = new Regex ( string . Format ( numberRegexPattern , Regex . Escape ( optionNumberParsingDecimalSeparator ) , Regex . Escape ( optionNumberParsingThousandSeparator ) ) , RegexOptions . IgnoreCase ) ;
575
+ numberRegexPattern = string . Format ( numberRegexOrigPattern ,
576
+ optionNumberParsingDecimalSeparator != null ? Regex . Escape ( optionNumberParsingDecimalSeparator ) : "." ,
577
+ optionNumberParsingThousandSeparator != null ? Regex . Escape ( optionNumberParsingThousandSeparator ) : "" ) ;
581
578
}
582
579
}
583
580
@@ -600,9 +597,10 @@ public string OptionNumberParsingThousandSeparator
600
597
{
601
598
optionNumberParsingThousandSeparator = value ?? string . Empty ;
602
599
CultureInfoForNumberParsing . NumberFormat . NumberGroupSeparator = value ;
603
-
604
- numberRegex = new Regex ( string . Format ( numberRegexPattern , Regex . Escape ( optionNumberParsingDecimalSeparator ) , Regex . Escape ( optionNumberParsingThousandSeparator ) ) , RegexOptions . IgnoreCase ) ;
605
-
600
+
601
+ numberRegexPattern = string . Format ( numberRegexOrigPattern ,
602
+ optionNumberParsingDecimalSeparator != null ? Regex . Escape ( optionNumberParsingDecimalSeparator ) : "." ,
603
+ optionNumberParsingThousandSeparator != null ? Regex . Escape ( optionNumberParsingThousandSeparator ) : "" ) ;
606
604
}
607
605
}
608
606
@@ -640,8 +638,6 @@ public bool OptionInlineNamespacesEvaluationActive
640
638
set
641
639
{
642
640
optionInlineNamespacesEvaluationActive = value ;
643
- instanceCreationWithNewKeywordRegex = new Regex ( InstanceCreationWithNewKeywordRegexPattern , ( optionCaseSensitiveEvaluationActive ? RegexOptions . None : RegexOptions . IgnoreCase ) ) ;
644
- castRegex = new Regex ( CastRegexPattern , ( optionCaseSensitiveEvaluationActive ? RegexOptions . None : RegexOptions . IgnoreCase ) ) ;
645
641
}
646
642
}
647
643
@@ -836,10 +832,10 @@ public Dictionary<string, object> Variables
836
832
public ExpressionEvaluator ( )
837
833
{
838
834
Assemblies . AddRange ( AppDomain . CurrentDomain . GetAssemblies ( ) ) ;
839
- instanceCreationWithNewKeywordRegex = new Regex ( InstanceCreationWithNewKeywordRegexPattern ) ;
840
- numberRegex = new Regex ( string . Format ( numberRegexPattern , @"\." , string . Empty ) , RegexOptions . IgnoreCase ) ;
835
+
836
+ numberRegexPattern = string . Format ( numberRegexPattern , @"\." , string . Empty ) ;
837
+
841
838
CultureInfoForNumberParsing . NumberFormat . NumberDecimalSeparator = "." ;
842
- castRegex = new Regex ( CastRegexPattern ) ;
843
839
}
844
840
845
841
/// <summary>
@@ -915,7 +911,6 @@ private object ScriptEvaluate(string script, ref bool valueReturned, ref bool br
915
911
916
912
object ManageJumpStatementsOrExpressionEval ( string expression )
917
913
{
918
- string baseExpression = expression ;
919
914
object result = null ;
920
915
921
916
expression = expression . Trim ( ) ;
@@ -1454,7 +1449,7 @@ public object Evaluate(string expression)
1454
1449
1455
1450
private bool EvaluateCast ( string restOfExpression , Stack < object > stack , ref int i )
1456
1451
{
1457
- Match castMatch = castRegex . Match ( restOfExpression ) ;
1452
+ Match castMatch = Regex . Match ( restOfExpression , CastRegexPattern , optionCaseSensitiveEvaluationActive ? RegexOptions . None : RegexOptions . IgnoreCase ) ;
1458
1453
1459
1454
if ( castMatch . Success )
1460
1455
{
@@ -1476,7 +1471,7 @@ private bool EvaluateCast(string restOfExpression, Stack<object> stack, ref int
1476
1471
1477
1472
private bool EvaluateNumber ( string restOfExpression , Stack < object > stack , ref int i )
1478
1473
{
1479
- Match numberMatch = numberRegex . Match ( restOfExpression ) ;
1474
+ Match numberMatch = Regex . Match ( restOfExpression , numberRegexPattern , RegexOptions . IgnoreCase ) ;
1480
1475
Match otherBaseMatch = otherBasesNumberRegex . Match ( restOfExpression ) ;
1481
1476
1482
1477
if ( otherBaseMatch . Success
@@ -1542,7 +1537,7 @@ private bool EvaluateInstanceCreationWithNewKeyword(string expr, string restOfEx
1542
1537
if ( ! OptionNewKeywordEvaluationActive )
1543
1538
return false ;
1544
1539
1545
- Match instanceCreationMatch = instanceCreationWithNewKeywordRegex . Match ( restOfExpression ) ;
1540
+ Match instanceCreationMatch = Regex . Match ( restOfExpression , InstanceCreationWithNewKeywordRegexPattern , optionCaseSensitiveEvaluationActive ? RegexOptions . None : RegexOptions . IgnoreCase ) ;
1546
1541
1547
1542
if ( instanceCreationMatch . Success &&
1548
1543
( stack . Count == 0
@@ -2890,10 +2885,10 @@ private Type GetTypeByFriendlyName(string typeName, string genericTypes = "", bo
2890
2885
2891
2886
if ( result == null )
2892
2887
{
2893
- typeName = primaryTypesRegex . Replace ( typeName , delegate ( Match match )
2888
+ typeName = Regex . Replace ( typeName , primaryTypesRegexPattern , delegate ( Match match )
2894
2889
{
2895
2890
return primaryTypesDict [ match . Value . ManageCasing ( OptionCaseSensitiveEvaluationActive ) ] . ToString ( ) ;
2896
- } ) ;
2891
+ } , ( optionCaseSensitiveEvaluationActive ? RegexOptions . None : RegexOptions . IgnoreCase ) ) ;
2897
2892
2898
2893
result = Type . GetType ( typeName , false , ! OptionCaseSensitiveEvaluationActive ) ;
2899
2894
}
0 commit comments