Do not report a fix that --ignore-regex made impossible (#3994)
diff --git a/codespell_lib/_codespell.py b/codespell_lib/_codespell.py
index 994c5c4..e7d94aa 100644
--- a/codespell_lib/_codespell.py
+++ b/codespell_lib/_codespell.py
@@ -1093,11 +1093,15 @@
                     continue
 
                 if options.write_changes and fix:
-                    changed = True
-                    lines[i] = re.sub(rf"\b{word}\b", fixword, lines[i])
-                    fixed_words.add(word)
-                    changes_made.append((line_number + 1, word, fixword))
-                    continue
+                    new_line = re.sub(rf"\b{word}\b", fixword, lines[i])
+                    if new_line != lines[i]:
+                        changed = True
+                        lines[i] = new_line
+                        fixed_words.add(word)
+                        changes_made.append((line_number + 1, word, fixword))
+                        continue
+                    # Not found in the original line (e.g. --ignore-regex split
+                    # it out of a larger word), so report it instead (GH-2056).
 
                 # otherwise warning was explicitly set by interactive mode
                 if (
diff --git a/codespell_lib/tests/test_basic.py b/codespell_lib/tests/test_basic.py
index 930f09f..c82d847 100644
--- a/codespell_lib/tests/test_basic.py
+++ b/codespell_lib/tests/test_basic.py
@@ -1054,6 +1054,34 @@
     assert cs.main(fname, r"--ignore-regex=\bdonn\b") == 1
 
 
+def test_ignore_regex_with_write_changes(
+    tmp_path: Path,
+    capsys: pytest.CaptureFixture[str],
+) -> None:
+    """Test that -w never claims a fix it did not perform (gh-2056)."""
+    fname = tmp_path / "flag.txt"
+    content = "1nd\n1nd_2nd\n"
+
+    # Without -w, --ignore-regex=_ makes BOTH lines report a misspelling.
+    fname.write_text(content)
+    assert cs.main(fname, "--ignore-regex=_") == 2
+
+    fname.write_text(content)
+    result = cs.main("-w", "--ignore-regex=_", fname, std=True)
+    assert isinstance(result, tuple)
+    code, stdout, stderr = result
+    corrected = fname.read_text()
+
+    # Line 1 really is rewritten.
+    assert corrected == "1st\n1nd_2nd\n"
+    # Line 2 cannot be rewritten (\b1nd\b does not match "1nd_2nd"), so it must
+    # not be listed as fixed, must be reported as a misspelling instead ...
+    assert "flag.txt:2: 1nd ==> 1st" not in stderr
+    assert "flag.txt:2: 1nd ==> 1st" in stdout
+    # ... and must be counted, so that it affects the exit code.
+    assert code == 1
+
+
 def test_ignore_multiline_regex_option(
     tmp_path: Path,
     capsys: pytest.CaptureFixture[str],