@@ -17,19 +17,32 @@ static class FormulaParser
1717 internal static bool TryGetFormulaInfo ( string formulaPrefix , out string functionName , out int currentArgIndex )
1818 {
1919 Debug . Assert ( formulaPrefix != null ) ;
20-
20+
21+ // Hide the strings, in order to ignore the commas, parenthesis and curly brackets which might be inside.
22+ // Ex: =SomeFunction("a", "b,c(d,{e,f,
23+ // In the example above, the function is SomeFunction, and the index is 2
24+
25+ // If editing a string, then close the double-quotes
2126 if ( formulaPrefix . Count ( c => c == '\" ' ) % 2 != 0 )
2227 {
2328 formulaPrefix = string . Concat ( formulaPrefix , '\" ' ) ;
2429 }
2530
26- formulaPrefix = Regex . Replace ( formulaPrefix , "(\" [^\" ]*\" )|(\\ ([^\\ (\\ )]*\\ ))| " , string . Empty ) ;
31+ // Remove the strings.
32+ // Note: in Excel, in order to put a double-quotes in a string, one has to double the double-quotes.
33+ // For instance, "a""b" for a"b. Since we only want to hide the strings in order to count the commas,
34+ // the regex below still applies.
35+ formulaPrefix = Regex . Replace ( formulaPrefix , "(\" [^\" ]*\" )" , string . Empty ) ;
36+
37+ // Remove sub-formulae
38+ formulaPrefix = Regex . Replace ( formulaPrefix , "(\\ ([^\\ (\\ )]*\\ ))| " , string . Empty ) ;
2739
2840 while ( Regex . IsMatch ( formulaPrefix , "\\ ([^\\ (\\ )]*\\ )" ) )
2941 {
3042 formulaPrefix = Regex . Replace ( formulaPrefix , "\\ ([^\\ (\\ )]*\\ )" , string . Empty ) ;
3143 }
3244
45+ // Find the function name and the argument index
3346 int lastOpeningParenthesis = formulaPrefix . LastIndexOf ( "(" , formulaPrefix . Length - 1 , StringComparison . Ordinal ) ;
3447
3548 if ( lastOpeningParenthesis > - 1 )
@@ -38,7 +51,24 @@ internal static bool TryGetFormulaInfo(string formulaPrefix, out string function
3851 if ( match . Success )
3952 {
4053 functionName = match . Groups [ functionNameGroupName ] . Value ;
41- currentArgIndex = formulaPrefix . Substring ( lastOpeningParenthesis , formulaPrefix . Length - lastOpeningParenthesis ) . Count ( c => c == ListSeparator ) ;
54+
55+ string argumentsPart = formulaPrefix . Substring ( lastOpeningParenthesis , formulaPrefix . Length - lastOpeningParenthesis ) ;
56+
57+ // Hide array formulae
58+ // Ex: =SomeFunction("a", {"a", "b", "c"
59+ // In the example above the index is 2
60+
61+ // If editing an array, then close the curly bracket.
62+ // Since we already removed the strings, there won't be any curly brackets within a string.
63+ if ( argumentsPart . Count ( c => c == '{' ) > argumentsPart . Count ( c => c == '}' ) )
64+ {
65+ argumentsPart = string . Concat ( argumentsPart , '}' ) ;
66+ }
67+
68+ // Remove the arrays.
69+ argumentsPart = Regex . Replace ( argumentsPart , "(\\ {[^\\ }]*\\ })" , string . Empty ) ;
70+
71+ currentArgIndex = argumentsPart . Count ( c => c == ListSeparator ) ;
4272 return true ;
4373 }
4474 }
0 commit comments