Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -834,8 +834,9 @@ def _promote_misplaced_header_row(grid):
|
|
| 834 |
# Matches a value suffix fused onto a label with no space.
|
| 835 |
# e.g. "Beginning Interest Rate0.00%" β label + "0.00%"
|
| 836 |
# "Number of days in this Period31" β label + "31"
|
|
|
|
| 837 |
_FUSED_KV_RE = re.compile(
|
| 838 |
-
r"^(.+?)
|
| 839 |
re.DOTALL,
|
| 840 |
)
|
| 841 |
|
|
@@ -846,14 +847,28 @@ def _fix_fused_keyvalue_rows(grid):
|
|
| 846 |
cells empty β common in Interest Summary / Fee Summary sections appended
|
| 847 |
to a transaction table by OCR.
|
| 848 |
|
|
|
|
|
|
|
|
|
|
| 849 |
Guard conditions (no-op if not met β safe for all other tables):
|
| 850 |
- All cells except first must be empty.
|
| 851 |
- A non-space character must immediately precede the digit run (fused).
|
| 852 |
- Both label and value parts must be non-empty after splitting.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 853 |
"""
|
| 854 |
if not grid or len(grid) < 2:
|
| 855 |
return grid
|
| 856 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 857 |
ncols = len(grid[0])
|
| 858 |
new_grid = [grid[0]]
|
| 859 |
|
|
@@ -870,8 +885,15 @@ def _fix_fused_keyvalue_rows(grid):
|
|
| 870 |
new_grid.append(row)
|
| 871 |
continue
|
| 872 |
|
| 873 |
-
#
|
| 874 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 875 |
new_grid.append(row)
|
| 876 |
continue
|
| 877 |
|
|
@@ -880,9 +902,16 @@ def _fix_fused_keyvalue_rows(grid):
|
|
| 880 |
new_grid.append(row)
|
| 881 |
continue
|
| 882 |
|
| 883 |
-
|
| 884 |
value = m.group(2).strip()
|
| 885 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 886 |
if not label or not value:
|
| 887 |
new_grid.append(row)
|
| 888 |
continue
|
|
|
|
| 834 |
# Matches a value suffix fused onto a label with no space.
|
| 835 |
# e.g. "Beginning Interest Rate0.00%" β label + "0.00%"
|
| 836 |
# "Number of days in this Period31" β label + "31"
|
| 837 |
+
# Strict: no \s* between groups so label trailing-space detects space-separated values
|
| 838 |
_FUSED_KV_RE = re.compile(
|
| 839 |
+
r"^(.+?)(-?\d{1,3}(?:,\d{3})*(?:\.\d+)?%?)$",
|
| 840 |
re.DOTALL,
|
| 841 |
)
|
| 842 |
|
|
|
|
| 847 |
cells empty β common in Interest Summary / Fee Summary sections appended
|
| 848 |
to a transaction table by OCR.
|
| 849 |
|
| 850 |
+
e.g. "Beginning Interest Rate0.00%" β label="Beginning Interest Rate" value="0.00%"
|
| 851 |
+
"Number of days in this Period31" β label="..." value="31"
|
| 852 |
+
|
| 853 |
Guard conditions (no-op if not met β safe for all other tables):
|
| 854 |
- All cells except first must be empty.
|
| 855 |
- A non-space character must immediately precede the digit run (fused).
|
| 856 |
- Both label and value parts must be non-empty after splitting.
|
| 857 |
+
- The cell must NOT contain an account number (7+ digit run) β prevents
|
| 858 |
+
incorrectly splitting "STREAMLINED CHECKING #208479667" or
|
| 859 |
+
"Charges debited from account #208479667".
|
| 860 |
+
- The cell must NOT contain a proper dollar amount with decimal β prevents
|
| 861 |
+
incorrectly splitting metadata like "Beginning Balance:$20.48$3.46".
|
| 862 |
"""
|
| 863 |
if not grid or len(grid) < 2:
|
| 864 |
return grid
|
| 865 |
|
| 866 |
+
# Matches a proper dollar/currency amount with decimal point β these appear
|
| 867 |
+
# in legitimate label cells and must not trigger the fused-KV split.
|
| 868 |
+
_DOLLAR_AMOUNT_RE = re.compile(r"\$\s*\d{1,3}(?:,\d{3})*\.\d{2}")
|
| 869 |
+
# Matches a long account/reference number (7+ consecutive digits)
|
| 870 |
+
_LONG_NUMBER_RE = re.compile(r"\d{7,}")
|
| 871 |
+
|
| 872 |
ncols = len(grid[0])
|
| 873 |
new_grid = [grid[0]]
|
| 874 |
|
|
|
|
| 885 |
new_grid.append(row)
|
| 886 |
continue
|
| 887 |
|
| 888 |
+
# Guard: skip rows containing a proper dollar amount with decimal
|
| 889 |
+
# (these are metadata/balance rows, not fused key-value summary rows)
|
| 890 |
+
if _DOLLAR_AMOUNT_RE.search(first):
|
| 891 |
+
new_grid.append(row)
|
| 892 |
+
continue
|
| 893 |
+
|
| 894 |
+
# Guard: skip rows containing a long account/reference number (7+ digits)
|
| 895 |
+
# (e.g. "STREAMLINED CHECKING #208479667", "account #208479667")
|
| 896 |
+
if _LONG_NUMBER_RE.search(first):
|
| 897 |
new_grid.append(row)
|
| 898 |
continue
|
| 899 |
|
|
|
|
| 902 |
new_grid.append(row)
|
| 903 |
continue
|
| 904 |
|
| 905 |
+
label_raw = m.group(1) # trailing space means value was space-separated, not fused
|
| 906 |
value = m.group(2).strip()
|
| 907 |
|
| 908 |
+
# Space before value means NOT fused β "Interest Rate 0.00%" is clean
|
| 909 |
+
if label_raw != label_raw.rstrip():
|
| 910 |
+
new_grid.append(row)
|
| 911 |
+
continue
|
| 912 |
+
|
| 913 |
+
label = label_raw.strip()
|
| 914 |
+
|
| 915 |
if not label or not value:
|
| 916 |
new_grid.append(row)
|
| 917 |
continue
|