11/******************************************************************************************************
22 Title : ExpressionEvaluator (https://github.com/codingseb/ExpressionEvaluator)
3- Version : 1.3.3.3
3+ Version : 1.3.3.4
44 (if last digit (the forth) is not a zero, the version is an intermediate version and can be unstable)
55
66 Author : Coding Seb
@@ -33,7 +33,7 @@ public class ExpressionEvaluator
3333
3434 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 ) ;
3535
36- private string numberRegexPattern = @"^(?<sign>[+-])?([0-9][0-9_]*[0-9]|\d)(?<hasdecimal>{0}?([0-9][0-9_]*[0-9]|\d)(e[+-]?([0-9][0-9_]*[0-9]|\d))?)?(?<type>ul|[fdulm])?" ;
36+ private 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])?" ;
3737 private Regex numberRegex = null ;
3838
3939 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 ) ;
@@ -533,12 +533,36 @@ private StringComparer StringComparerForCasing
533533 }
534534
535535 private CultureInfo cultureInfoForNumberParsing = CultureInfo . InvariantCulture . Clone ( ) as CultureInfo ;
536+
536537 private string optionNumberParsingDecimalSeparator = "." ;
537538
539+ /// <summary>
540+ /// The culture used to evaluate numbers
541+ /// Synchronized with OptionNumberParsingDecimalSeparator and OptionNumberParsingThousandSeparator.
542+ /// So always set a full CultureInfo object and do not change NumberFormat.NumberDecimalSeparator and NumberFormat.NumberGroupSeparator properties directly.
543+ /// Warning if using comma in separators change also OptionFunctionArgumentsSeparator and OptionInitializersSeparator otherwise it will create conflicts
544+ /// </summary>
545+ public CultureInfo CultureInfoForNumberParsing
546+ {
547+ get
548+ {
549+ return cultureInfoForNumberParsing ;
550+ }
551+
552+ set
553+ {
554+ cultureInfoForNumberParsing = value ;
555+
556+ OptionNumberParsingDecimalSeparator = cultureInfoForNumberParsing . NumberFormat . NumberDecimalSeparator ;
557+ OptionNumberParsingThousandSeparator = cultureInfoForNumberParsing . NumberFormat . NumberGroupSeparator ;
558+ }
559+ }
560+
538561 /// <summary>
539562 /// Allow to change the decimal separator of numbers when parsing expressions.
540563 /// By default "."
541- /// Warning if using comma change also OptionFunctionArgumentsSeparator and OptionInitializersSeparator otherwise it will create conflicts
564+ /// Warning if using comma change also OptionFunctionArgumentsSeparator and OptionInitializersSeparator otherwise it will create conflicts.
565+ /// Modify CultureInfoForNumberParsing.
542566 /// </summary>
543567 public string OptionNumberParsingDecimalSeparator
544568 {
@@ -548,9 +572,32 @@ public string OptionNumberParsingDecimalSeparator
548572 set
549573 {
550574 optionNumberParsingDecimalSeparator = value ;
551- cultureInfoForNumberParsing . NumberFormat . NumberDecimalSeparator = value ;
575+ CultureInfoForNumberParsing . NumberFormat . NumberDecimalSeparator = value ;
576+
577+ numberRegex = new Regex ( string . Format ( numberRegexPattern , Regex . Escape ( optionNumberParsingDecimalSeparator ) , Regex . Escape ( optionNumberParsingThousandSeparator ) ) , RegexOptions . IgnoreCase ) ;
578+ }
579+ }
580+
581+ /// <summary>
582+ /// Allow to change the thousand separator of numbers when parsing expressions.
583+ /// By default string.Empty
584+ /// Warning if using comma change also OptionFunctionArgumentsSeparator and OptionInitializersSeparator otherwise it will create conflicts.
585+ /// Modify CultureInfoForNumberParsing.
586+ /// </summary>
587+ public string OptionNumberParsingThousandSeparator
588+ {
589+ get
590+ {
591+ return optionNumberParsingThousandSeparator ;
592+ }
593+
594+ set
595+ {
596+ optionNumberParsingThousandSeparator = value ;
597+ CultureInfoForNumberParsing . NumberFormat . NumberGroupSeparator = value ;
598+
599+ numberRegex = new Regex ( string . Format ( numberRegexPattern , Regex . Escape ( optionNumberParsingDecimalSeparator ) , Regex . Escape ( optionNumberParsingThousandSeparator ) ) , RegexOptions . IgnoreCase ) ;
552600
553- numberRegex = new Regex ( string . Format ( numberRegexPattern , Regex . Escape ( optionNumberParsingDecimalSeparator ) ) , RegexOptions . IgnoreCase ) ;
554601 }
555602 }
556603
@@ -786,7 +833,7 @@ public ExpressionEvaluator()
786833 Assemblies . AddRange ( AppDomain . CurrentDomain . GetAssemblies ( ) ) ;
787834 instanceCreationWithNewKeywordRegex = new Regex ( InstanceCreationWithNewKeywordRegexPattern ) ;
788835 numberRegex = new Regex ( string . Format ( numberRegexPattern , @"\." ) , RegexOptions . IgnoreCase ) ;
789- cultureInfoForNumberParsing . NumberFormat . NumberDecimalSeparator = "." ;
836+ CultureInfoForNumberParsing . NumberFormat . NumberDecimalSeparator = "." ;
790837 castRegex = new Regex ( CastRegexPattern ) ;
791838 }
792839
@@ -804,6 +851,7 @@ public ExpressionEvaluator(Dictionary<string, object> variables) : this()
804851 #region Main evaluate methods (Expressions and scripts ==> public)
805852
806853 private bool inScript = false ;
854+ private string optionNumberParsingThousandSeparator ;
807855
808856 /// <summary>
809857 /// Evaluate a script (multiple expressions separated by semicolon)
@@ -1462,18 +1510,18 @@ private bool EvaluateNumber(string restOfExpression, Stack<object> stack, ref in
14621510
14631511 if ( numberSuffixToParse . TryGetValue ( type , out Func < string , CultureInfo , object > parseFunc ) )
14641512 {
1465- stack . Push ( parseFunc ( numberNoType , cultureInfoForNumberParsing ) ) ;
1513+ stack . Push ( parseFunc ( numberNoType , CultureInfoForNumberParsing ) ) ;
14661514 }
14671515 }
14681516 else
14691517 {
14701518 if ( numberMatch . Groups [ "hasdecimal" ] . Success )
14711519 {
1472- stack . Push ( double . Parse ( numberMatch . Value . Replace ( "_" , "" ) , NumberStyles . Any , cultureInfoForNumberParsing ) ) ;
1520+ stack . Push ( double . Parse ( numberMatch . Value . Replace ( "_" , "" ) , NumberStyles . Any , CultureInfoForNumberParsing ) ) ;
14731521 }
14741522 else
14751523 {
1476- stack . Push ( int . Parse ( numberMatch . Value . Replace ( "_" , "" ) , NumberStyles . Any , cultureInfoForNumberParsing ) ) ;
1524+ stack . Push ( int . Parse ( numberMatch . Value . Replace ( "_" , "" ) , NumberStyles . Any , CultureInfoForNumberParsing ) ) ;
14771525 }
14781526 }
14791527
0 commit comments