utils(string): add support for floating point numbers

This commit is contained in:
Aleix Conchillo Flaqué
2025-02-26 18:22:37 -08:00
parent 1dbad2326a
commit 11984b89b7
3 changed files with 29 additions and 8 deletions

View File

@@ -8,7 +8,8 @@ import re
ENDOFSENTENCE_PATTERN_STR = r"""
(?<![A-Z]) # Negative lookbehind: not preceded by an uppercase letter (e.g., "U.S.A.")
(?<!\d) # Negative lookbehind: not preceded by a digit (e.g., "1. Let's start")
(?<!\d\.\d) # Not preceded by a decimal number (e.g., "3.14159")
(?<!^\d\.) # Not preceded by a numbered list item (e.g., "1. Let's start")
(?<!\d\s[ap]) # Negative lookbehind: not preceded by time (e.g., "3:00 a.m.")
(?<!Mr|Ms|Dr) # Negative lookbehind: not preceded by Mr, Ms, Dr (combined bc. length is the same)
(?<!Mrs) # Negative lookbehind: not preceded by "Mrs"
@@ -22,19 +23,30 @@ ENDOFSENTENCE_PATTERN = re.compile(ENDOFSENTENCE_PATTERN_STR, re.VERBOSE)
EMAIL_PATTERN = re.compile(r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}")
NUMBER_PATTERN = re.compile(r"[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?")
def replace_match(text: str, match: re.Match, old: str, new: str) -> str:
start = match.start()
end = match.end()
replacement = text[start:end].replace(old, new)
text = text[:start] + replacement + text[end:]
return text
def match_endofsentence(text: str) -> int:
text = text.rstrip()
# Find all emails.
# Replace email dots by ampersands so we can find the end of sentence. For
# example, first.last@email.com becomes first&last@email&com.
emails = list(EMAIL_PATTERN.finditer(text))
# Replace email dots by ampersands so we can find the end of sentence.
for email_match in emails:
start = email_match.start()
end = email_match.end()
new_email = text[start:end].replace(".", "&")
text = text[:start] + new_email + text[end:]
text = replace_match(text, email_match, ".", "&")
# Replace number dots by ampersands so we can find the end of sentence.
numbers = list(NUMBER_PATTERN.finditer(text))
for number_match in numbers:
text = replace_match(text, number_match, ".", "&")
# Match against the new text.
match = ENDOFSENTENCE_PATTERN.search(text)