1
1
/******************************************************************************************************
2
2
Title : ExpressionEvaluator (https://github.com/codingseb/ExpressionEvaluator)
3
- Version : 1.3.3.3
3
+ Version : 1.3.3.4
4
4
(if last digit (the forth) is not a zero, the version is an intermediate version and can be unstable)
5
5
6
6
Author : Coding Seb
@@ -33,7 +33,7 @@ public class ExpressionEvaluator
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 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])?" ;
37
37
private Regex numberRegex = 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 ) ;
@@ -533,12 +533,36 @@ private StringComparer StringComparerForCasing
533
533
}
534
534
535
535
private CultureInfo cultureInfoForNumberParsing = CultureInfo . InvariantCulture . Clone ( ) as CultureInfo ;
536
+
536
537
private string optionNumberParsingDecimalSeparator = "." ;
537
538
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
+
538
561
/// <summary>
539
562
/// Allow to change the decimal separator of numbers when parsing expressions.
540
563
/// 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.
542
566
/// </summary>
543
567
public string OptionNumberParsingDecimalSeparator
544
568
{
@@ -548,9 +572,32 @@ public string OptionNumberParsingDecimalSeparator
548
572
set
549
573
{
550
574
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 ) ;
552
600
553
- numberRegex = new Regex ( string . Format ( numberRegexPattern , Regex . Escape ( optionNumberParsingDecimalSeparator ) ) , RegexOptions . IgnoreCase ) ;
554
601
}
555
602
}
556
603
@@ -786,7 +833,7 @@ public ExpressionEvaluator()
786
833
Assemblies . AddRange ( AppDomain . CurrentDomain . GetAssemblies ( ) ) ;
787
834
instanceCreationWithNewKeywordRegex = new Regex ( InstanceCreationWithNewKeywordRegexPattern ) ;
788
835
numberRegex = new Regex ( string . Format ( numberRegexPattern , @"\." ) , RegexOptions . IgnoreCase ) ;
789
- cultureInfoForNumberParsing . NumberFormat . NumberDecimalSeparator = "." ;
836
+ CultureInfoForNumberParsing . NumberFormat . NumberDecimalSeparator = "." ;
790
837
castRegex = new Regex ( CastRegexPattern ) ;
791
838
}
792
839
@@ -804,6 +851,7 @@ public ExpressionEvaluator(Dictionary<string, object> variables) : this()
804
851
#region Main evaluate methods (Expressions and scripts ==> public)
805
852
806
853
private bool inScript = false ;
854
+ private string optionNumberParsingThousandSeparator ;
807
855
808
856
/// <summary>
809
857
/// Evaluate a script (multiple expressions separated by semicolon)
@@ -1462,18 +1510,18 @@ private bool EvaluateNumber(string restOfExpression, Stack<object> stack, ref in
1462
1510
1463
1511
if ( numberSuffixToParse . TryGetValue ( type , out Func < string , CultureInfo , object > parseFunc ) )
1464
1512
{
1465
- stack . Push ( parseFunc ( numberNoType , cultureInfoForNumberParsing ) ) ;
1513
+ stack . Push ( parseFunc ( numberNoType , CultureInfoForNumberParsing ) ) ;
1466
1514
}
1467
1515
}
1468
1516
else
1469
1517
{
1470
1518
if ( numberMatch . Groups [ "hasdecimal" ] . Success )
1471
1519
{
1472
- stack . Push ( double . Parse ( numberMatch . Value . Replace ( "_" , "" ) , NumberStyles . Any , cultureInfoForNumberParsing ) ) ;
1520
+ stack . Push ( double . Parse ( numberMatch . Value . Replace ( "_" , "" ) , NumberStyles . Any , CultureInfoForNumberParsing ) ) ;
1473
1521
}
1474
1522
else
1475
1523
{
1476
- stack . Push ( int . Parse ( numberMatch . Value . Replace ( "_" , "" ) , NumberStyles . Any , cultureInfoForNumberParsing ) ) ;
1524
+ stack . Push ( int . Parse ( numberMatch . Value . Replace ( "_" , "" ) , NumberStyles . Any , CultureInfoForNumberParsing ) ) ;
1477
1525
}
1478
1526
}
1479
1527
0 commit comments