Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Notable changes to the `phileas-redact` package, most recent first.

## Unreleased

* The `streetAddress` filter no longer matches across a line break. The parts of an address were joined by `\s`, which includes line breaks, so a number at the end of one line and a word and a street type on the next were read as an address: in `Cedar Falls, IA 50613`, a blank line, and `Dear Dr. Rivera,`, the text from `50613` to `Dr` was detected, with `Dr` read as Drive. The parts are now joined by spaces and tabs, as in Phileas (Java), so an address on one line and the street line of a multi-line address block are found as before. Parts separated by other whitespace, such as a no-break space, no longer form an address. This is the parity port of the Phileas (Java) fix for philterd/phileas#474.
* The `phoneNumber` filter now finds a number written with a bare `1` country code and an area code beginning with 1, such as `1-112-997-5633`, `1 112 997 5633`, or `1-109-299-5128 x512`, when a configured `region` uses country code 1 (such as `US`, the default). libphonenumber read the `1` as the country code and the area code's `1` as a national prefix, leaving too few digits, so these were missed while `+1 112-997-5633` was found. A number found before keeps its span and confidence, and a number with no separators, such as `11129975633`, is still not found. Same as the Java library (philterd/phileas#458).
* The `RELATIVE` strategy now expresses a detected date relative to the current date (`3 months ago`, `2 years 1 months ago`), matching Phileas (Java). Previously it returned the date unchanged, leaving it in the document. A future date is written as `in 3 months` when the strategy sets `futureDates` to `true` and is redacted otherwise.
* A strategy no longer leaves a detected value in place when it cannot be applied. An unrecognized date under `SHIFT`, `TRUNCATE_TO_YEAR`, or `RELATIVE`, a value of 4 characters or fewer under `LAST_4` or `TRUNCATE`, and a filter type with no random generator under `RANDOM_REPLACE` are now redacted with the strategy's `redactionFormat`. A date-shaped value that is not a real date, such as `02/31/2020`, is treated as unrecognized instead of raising an error.
Expand Down
5 changes: 4 additions & 1 deletion phileas/filters/street_address_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@
from .base import BaseFilter, FilterType


# The parts are joined by spaces and tabs only, as in the Java filter, so a match does not
# run from one line into the next (a ZIP code at the end of a line and "Dear Dr." on the
# next are not an address).
_PATTERNS = [
re.compile(
r"\b\d{1,5}\s+(?:[A-Za-z0-9#.,\-]+\s+){1,4}"
r"\b\d{1,5}[ \t]+(?:[A-Za-z0-9#.,\-]+[ \t]+){1,4}"
r"(?:Street|St|Avenue|Ave|Boulevard|Blvd|Road|Rd|Lane|Ln|Drive|Dr|Court|Ct|Place|Pl|Way|Circle|Cir|Terrace|Ter|Trail|Trl)\b",
re.IGNORECASE,
),
Expand Down
23 changes: 23 additions & 0 deletions tests/test_street_address_detection.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,26 @@ def test_long_street_name_within_word_limit(street_filter):
assert spans[0].text == addr


def test_no_match_across_line_breaks(street_filter):
# A ZIP code at the end of a line and "Dear Dr." on the next line are not an address.
text = "Address: 214 Juniper Court, Cedar Falls, IA 50613\n\nDear Dr. Rivera,"
spans = street_filter.detect(text)
assert [s.text for s in spans] == ["214 Juniper Court"]


@pytest.mark.parametrize(
"text,expected",
[
("214 Juniper Court\nCedar Falls, IA 50613", "214 Juniper Court"),
("123 Main St Apt 4B\r\nSpringfield, IL 62704", "123 Main St"),
("Jane Doe\n1 Martin Luther King Jr Blvd\nAtlanta, GA 30303", "1 Martin Luther King Jr Blvd"),
],
)
def test_street_line_of_address_block(street_filter, text, expected):
spans = street_filter.detect(text)
assert [s.text for s in spans] == [expected]


def test_default_context_returns_results(street_filter):
spans = street_filter.detect("123 Main Street", context="default")
assert len(spans) == 1
Expand Down Expand Up @@ -146,6 +166,9 @@ def test_custom_context_still_detects(street_filter):
"123 Main Streets", # trailing 's' breaks the suffix word boundary
"123 Main Streetss",
"123456 Main Street", # number has six digits (exceeds \\d{1,5})
"Cedar Falls, IA 50613\nDear Dr. Rivera,", # parts on different lines
"Cedar Falls, IA 50613\r\nDear Dr. Rivera,",
"Unit 12\nMain Street",
],
)
def test_no_detection(street_filter, text):
Expand Down
Loading