Skip to content

Commit 2145483

Browse files
author
Sébastien Geiser
committed
Thousand separator and public CultureInfoForNumberParsing property to test
1 parent 368f41e commit 2145483

File tree

1 file changed

+57
-9
lines changed

1 file changed

+57
-9
lines changed

CodingSeb.ExpressionEvaluator/ExpressionEvaluator.cs

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
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

Comments
 (0)