Skip to content

Fix SUMIF/COUNTIF exact text matching to not match substrings#2267

Merged
xuri merged 5 commits into
qax-os:masterfrom
jpoz:jpoz/fix-SUMIFs
Mar 6, 2026
Merged

Fix SUMIF/COUNTIF exact text matching to not match substrings#2267
xuri merged 5 commits into
qax-os:masterfrom
jpoz:jpoz/fix-SUMIFs

Conversation

@jpoz
Copy link
Copy Markdown
Contributor

@jpoz jpoz commented Feb 27, 2026

PR Details

Fix formulaCriteriaParser to anchor regex patterns so that exact text criteria in SUMIF/COUNTIF do not incorrectly match substrings.

Description

Modified formulaCriteriaParser to wrap regex patterns with ^ and $ anchors. Previously, criteria like "administrative" would match substrings such as "cyclical_flat_administrative", producing incorrect results. With this fix, exact text criteria only match full cell values, while wildcard patterns (*, ?) continue to work as expected.

Related Issue

N/A

Motivation and Context

When using SUMIF(A2:A7,"administrative",B2:B7), the formula was matching cells containing "cyclical_flat_administrative" and "pre_administrative_post" in addition to "administrative". This is incorrect behavior — Excel only matches exact values when no wildcards are present. The fix ensures parity with Excel's behavior.

How Has This Been Tested

Added TestCalcSUMIFExactMatch which verifies:

  • Exact text match ("administrative") only matches full cell values (sum = 250, count = 2)
  • Wildcard *administrative* matches all cells containing the substring (sum = 750, count = 4)
  • Wildcard administrative* matches cells starting with the term
  • Wildcard *administrative matches cells ending with the term
  • Single char wildcard othe? matches as expected
  • All existing tests continue to pass

Types of changes

  • Docs change / refactoring / dependency upgrade
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

Modified formulaCriteriaParser to wrap regex patterns with ^ and $.
Prevents partial string matches in SUMIF/COUNTIF functions when
wildcards are not explicitly used.

Test verifies "administrative" matches exactly 2 cells, not 4
substring matches like "cyclical_flat_administrative".
@xuri xuri added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Feb 27, 2026
Changed logic to only use regex matching when wildcards are present.
Plain strings now use direct equality comparison, improving performance
for common use cases without pattern matching.
@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 27, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.56%. Comparing base (418be6d) to head (0314ef3).
⚠️ Report is 24 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff            @@
##           master    #2267    +/-   ##
========================================
  Coverage   99.55%   99.56%            
========================================
  Files          32       32            
  Lines       25778    26316   +538     
========================================
+ Hits        25663    26201   +538     
  Misses         60       60            
  Partials       55       55            
Flag Coverage Δ
unittests 99.56% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes SUMIF/COUNTIF criteria parsing so that plain-text criteria match whole cell values (not substrings), aligning behavior with Excel’s exact-match semantics when no wildcards are present.

Changes:

  • Updated formulaCriteriaParser to treat non-wildcard criteria as strict equality and wildcard criteria as anchored regex (^...$).
  • Added a regression test covering exact-match vs wildcard-match behavior for SUMIF and COUNTIF.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
calc.go Adjusts criteria parsing logic to prevent substring matches for non-wildcard text criteria and anchors wildcard patterns.
calc_test.go Adds coverage ensuring exact matches don’t match substrings and wildcard patterns behave as intended.
Comments suppressed due to low confidence (1)

calc.go:1868

  • In the wildcard branch, the criteria is converted into a Go regexp by only replacing ?/* and then wrapping with ^...$. Any other regexp metacharacters in the original criteria (e.g. ., +, [, \, ^, $) are currently interpreted as regexp syntax (or can even make the pattern invalid), which diverges from Excel semantics where only * and ? are special. Consider escaping the input first (e.g. regexp.QuoteMeta(val) or reusing matchPatternToRegExp-style escaping), then translating the escaped wildcards (and ideally supporting Excel's ~ escape for literal */?).
	hasWildcard := strings.Contains(val, "?") || strings.Contains(val, "*")
	if strings.Contains(val, "?") {
		val = strings.ReplaceAll(val, "?", ".")
	}
	if strings.Contains(val, "*") {
		val = strings.ReplaceAll(val, "*", ".*")
	}
	if hasWildcard {
		fc.Type, fc.Condition = criteriaRegexp, newStringFormulaArg("^"+val+"$")
	} else {

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread calc_test.go Outdated
Comment thread calc_test.go Outdated
Comment thread calc_test.go Outdated
Comment thread calc_test.go Outdated
Comment thread calc_test.go Outdated
Comment thread calc_test.go Outdated
@xuri xuri moved this to BugFix in Excelize v2.11.0 Mar 4, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Member

@xuri xuri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your PR. I made some changes based on your branch, add more test cases and simplify code.

@xuri xuri merged commit 37b6a8f into qax-os:master Mar 6, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/M Denotes a PR that changes 30-99 lines, ignoring generated files.

Projects

Status: BugFix

Development

Successfully merging this pull request may close these issues.

3 participants