From 11984b89b79661d6d7ae2e0987446434dfe8021b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleix=20Conchillo=20Flaqu=C3=A9?= Date: Wed, 26 Feb 2025 18:22:37 -0800 Subject: [PATCH] utils(string): add support for floating point numbers --- CHANGELOG.md | 3 +++ src/pipecat/utils/string.py | 28 ++++++++++++++++++++-------- tests/test_utils_string.py | 6 ++++++ 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e626a7b1..c530b0986 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -138,6 +138,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- Fixed a `match_endofsentence` issue that would result in floating point + numbers to be considered an end of sentence. + - Fixed a `match_endofsentence` issue that would result in emails to be considered an end of sentence. diff --git a/src/pipecat/utils/string.py b/src/pipecat/utils/string.py index 06f2fc175..a89127de9 100644 --- a/src/pipecat/utils/string.py +++ b/src/pipecat/utils/string.py @@ -8,7 +8,8 @@ import re ENDOFSENTENCE_PATTERN_STR = r""" (? 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) diff --git a/tests/test_utils_string.py b/tests/test_utils_string.py index 24519f724..ee0946d69 100644 --- a/tests/test_utils_string.py +++ b/tests/test_utils_string.py @@ -21,6 +21,11 @@ class TestUtilsString(unittest.IsolatedAsyncioTestCase): assert match_endofsentence("This is for Mr. and Mrs. Jones.") == 31 assert match_endofsentence("U.S.A and U.S.A..") == 17 assert match_endofsentence("My emails are foo@pipecat.ai and bar@pipecat.ai.") == 48 + assert match_endofsentence("My email is foo.bar@pipecat.ai.") == 31 + assert match_endofsentence("My email is spell(foo.bar@pipecat.ai).") == 38 + assert match_endofsentence("The number pi is 3.14159.") == 25 + assert match_endofsentence("Valid scientific notation 1.23e4.") == 33 + assert match_endofsentence("Valid scientific notation 0.e4.") == 31 assert not match_endofsentence("This is not a sentence") assert not match_endofsentence("This is not a sentence,") assert not match_endofsentence("This is not a sentence, ") @@ -32,6 +37,7 @@ class TestUtilsString(unittest.IsolatedAsyncioTestCase): assert not match_endofsentence("America, or the U.") # U.S.A. assert not match_endofsentence("It still early, it's 3:00 a.") # 3:00 a.m. assert not match_endofsentence("My emails are foo@pipecat.ai and bar@pipecat.ai") + assert not match_endofsentence("The number pi is 3.14159") async def test_endofsentence_zh(self): chinese_sentences = [