From 65b699979d2f02e16e30650e8f4d85d17d1553ae Mon Sep 17 00:00:00 2001 From: OSjoerdWie Date: Tue, 16 Jun 2026 20:34:00 +0200 Subject: [PATCH] Ensure more greedy cell name replacement for defined names (NO1_VARIABLE should not become NO2_VARIABLE or NP1_VARIABLE) --- src/xlsx/mod.rs | 60 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/src/xlsx/mod.rs b/src/xlsx/mod.rs index 28e70cb8..d39dc378 100644 --- a/src/xlsx/mod.rs +++ b/src/xlsx/mod.rs @@ -3460,7 +3460,7 @@ fn expand_shared_formula_with_offset_into( let mut token_end = 0; for (i, &c) in bytes.iter().enumerate() { - if !in_quote && (c.is_ascii_alphanumeric() || c == b'$' || c == b':') { + if !in_quote && (c.is_ascii_alphanumeric() || c == b'_' || c == b'$' || c == b':') { token_end = i + 1; } else { if token_start < token_end { @@ -4616,6 +4616,64 @@ mod tests { "한글 B1 テスト".to_owned() ); + assert_eq!( + replace_cell_names("ABS(AND(Q1934;AA1_SOMETHING))", (0, 1)).unwrap(), + "ABS(AND(R1934;AA1_SOMETHING))".to_owned() + ); + + assert_eq!( + replace_cell_names("ABS(AND(Q1934;AA1_SOMETHING))", (1, 0)).unwrap(), + "ABS(AND(Q1935;AA1_SOMETHING))".to_owned() + ); + + assert_eq!( + replace_cell_names("Z1+1", (0, 1)).unwrap(), + "AA1+1".to_owned() + ); + + assert_eq!( + replace_cell_names("Z9+3", (1, 0)).unwrap(), + "Z10+3".to_owned() + ); + + assert_eq!( + replace_cell_names("Z1+A3B", (0, 1)).unwrap(), + "AA1+A3B".to_owned() + ); + + assert_eq!( + replace_cell_names("Z1+A3B", (1, 0)).unwrap(), + "Z2+A3B".to_owned() + ); + + // Named range after a cell ref. + assert_eq!( + replace_cell_names("A6+NO1_VARIABLE", (0, 1)).unwrap(), + "B6+NO1_VARIABLE" + ); + assert_eq!( + replace_cell_names("A6+NO1_VARIABLE", (1, 0)).unwrap(), + "A7+NO1_VARIABLE" + ); + + // Named range before a cell ref. + assert_eq!( + replace_cell_names("NO1_VARIABLE+Q5", (0, 1)).unwrap(), + "NO1_VARIABLE+R5" + ); + + // Leading underscore named range — should pass through. + assert_eq!( + replace_cell_names("_PRIVATE+A1", (0, 1)).unwrap(), + "_PRIVATE+B1" + ); + + // Named range with multiple underscores. + assert_eq!( + replace_cell_names("NO1__DOUBLE+A1", (0, 1)).unwrap(), + "NO1__DOUBLE+B1" + ); + assert_eq!( replace_cell_names("ABC\"asd\"123", (1, 0)).unwrap(), "ABC\"asd\"123".to_owned()