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
32 changes: 15 additions & 17 deletions nameparser/config/regexes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,32 @@
re_emoji = re.compile('[' # lgtm[py/overly-large-range]
'\U0001F300-\U0001F64F'
'\U0001F680-\U0001F6FF'
'\u2600-\u26FF\u2700-\u27BF]+',
re.UNICODE)
'\u2600-\u26FF\u2700-\u27BF]+')

EMPTY_REGEX = re.compile('')

REGEXES = set([
("spaces", re.compile(r"\s+", re.U)),
("word", re.compile(r"(\w|\.)+", re.U)),
("mac", re.compile(r'^(ma?c)(\w{2,})', re.I | re.U)),
("initial", re.compile(r'^(\w\.|[A-Z])?$', re.U)),
("quoted_word", re.compile(r'(?<!\w)\'([^\s]*?)\'(?!\w)', re.U)),
("double_quotes", re.compile(r'\"(.*?)\"', re.U)),
("parenthesis", re.compile(r'\((.*?)\)', re.U)),
("roman_numeral", re.compile(r'^(X|IX|IV|V?I{0,3})$', re.I | re.U)),
("no_vowels",re.compile(r'^[^aeyiuo]+$', re.I | re.U)),
("period_not_at_end",re.compile(r'.*\..+$', re.I | re.U)),
("spaces", re.compile(r"\s+")),
("word", re.compile(r"(\w|\.)+")),
("mac", re.compile(r'^(ma?c)(\w{2,})', re.I)),
("initial", re.compile(r'^(\w\.|[A-Z])?$')),
("quoted_word", re.compile(r'(?<!\w)\'([^\s]*?)\'(?!\w)')),
("double_quotes", re.compile(r'\"(.*?)\"')),
("parenthesis", re.compile(r'\((.*?)\)')),
("roman_numeral", re.compile(r'^(X|IX|IV|V?I{0,3})$', re.I)),
("no_vowels",re.compile(r'^[^aeyiuo]+$', re.I)),
("period_not_at_end",re.compile(r'.*\..+$', re.I)),
("emoji",re_emoji),
("phd", re.compile(r'\s(ph\.?\s+d\.?)', re.I | re.U)),
("space_before_comma", re.compile(r'\s+,', re.U)),
("phd", re.compile(r'\s(ph\.?\s+d\.?)', re.I)),
("space_before_comma", re.compile(r'\s+,')),
("patronymic", re.compile(
r'(ovich|ovna|evich|evna|ichna|ilyich|kuzmich|lukich|fomich|fokich)$',
re.I | re.U,
re.I,
)),
("patronymic_cyrillic", re.compile(
r'(ович|овна|евич|евна|ична|ильич|кузьмич|лукич|фомич|фокич)$',
re.U,
)),
("period_abbreviation", re.compile(r'^[^\W\d_]{2,}\.$', re.U)),
("period_abbreviation", re.compile(r'^[^\W\d_]{2,}\.$')),
])
"""
All regular expressions used by the parser are precompiled and stored in the config.
Expand Down
6 changes: 3 additions & 3 deletions tests/test_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def test_can_change_global_constants(self) -> None:
def test_can_add_global_extra_nickname_delimiter(self) -> None:
# https://github.com/derek73/python-nameparser/issues/112
hn = HumanName("")
hn.C.extra_nickname_delimiters['curly_braces'] = re.compile(r'\{(.*?)\}', re.U)
hn.C.extra_nickname_delimiters['curly_braces'] = re.compile(r'\{(.*?)\}')
hn2 = HumanName("Benjamin {Ben} Franklin")
self.assertEqual(hn2.has_own_config, False)
self.m(hn2.nickname, "Ben", hn2)
Expand Down Expand Up @@ -141,7 +141,7 @@ def test_pickle_roundtrip_preserves_customizations(self) -> None:
c.titles.add('customtitle')
c.prefixes.add('customprefix')
c.titles.remove('hon')
c.extra_nickname_delimiters['curly_braces'] = re.compile(r'\{(.*?)\}', re.U)
c.extra_nickname_delimiters['curly_braces'] = re.compile(r'\{(.*?)\}')

# Safe: round-tripping a Constants the test just built, not untrusted data.
restored = pickle.loads(pickle.dumps(c))
Expand Down Expand Up @@ -209,7 +209,7 @@ def test_extra_nickname_delimiters_deepcopy_roundtrip(self) -> None:
rather than only incidentally via conftest's autouse snapshot/restore.
"""
c = Constants()
c.extra_nickname_delimiters['curly_braces'] = re.compile(r'\{(.*?)\}', re.U)
c.extra_nickname_delimiters['curly_braces'] = re.compile(r'\{(.*?)\}')

dup = copy.deepcopy(c.extra_nickname_delimiters)

Expand Down
12 changes: 6 additions & 6 deletions tests/test_nicknames.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ def test_add_custom_nickname_delimiter(self) -> None:
hn = HumanName("Benjamin {Ben} Franklin", constants=None)
# curly braces aren't a recognized delimiter by default
self.m(hn.nickname, "", hn)
hn.C.extra_nickname_delimiters['curly_braces'] = re.compile(r'\{(.*?)\}', re.U)
hn.C.extra_nickname_delimiters['curly_braces'] = re.compile(r'\{(.*?)\}')
hn.parse_full_name()
self.m(hn.first, "Benjamin", hn)
self.m(hn.last, "Franklin", hn)
self.m(hn.nickname, "Ben", hn)

def test_remove_custom_nickname_delimiter(self) -> None:
hn = HumanName("Benjamin {Ben} Franklin", constants=None)
hn.C.extra_nickname_delimiters['curly_braces'] = re.compile(r'\{(.*?)\}', re.U)
hn.C.extra_nickname_delimiters['curly_braces'] = re.compile(r'\{(.*?)\}')
hn.parse_full_name()
self.m(hn.nickname, "Ben", hn)
del hn.C.extra_nickname_delimiters['curly_braces']
Expand All @@ -40,8 +40,8 @@ def test_multiple_custom_nickname_delimiters_together(self) -> None:
# Two extras registered at once must both be recognized in a single
# parse, independent of insertion order.
hn = HumanName("Benjamin {Ben} <Benny> Franklin", constants=None)
hn.C.extra_nickname_delimiters['curly_braces'] = re.compile(r'\{(.*?)\}', re.U)
hn.C.extra_nickname_delimiters['angle_brackets'] = re.compile(r'<(.*?)>', re.U)
hn.C.extra_nickname_delimiters['curly_braces'] = re.compile(r'\{(.*?)\}')
hn.C.extra_nickname_delimiters['angle_brackets'] = re.compile(r'<(.*?)>')
hn.parse_full_name()
self.m(hn.first, "Benjamin", hn)
self.m(hn.last, "Franklin", hn)
Expand All @@ -53,7 +53,7 @@ def test_overriding_builtin_regex_still_affects_nickname_parsing(self) -> None:
# parse_nicknames() also consults extra_nickname_delimiters.
hn = HumanName("Benjamin [Ben] Franklin", constants=None)
self.m(hn.nickname, "", hn)
hn.C.regexes['parenthesis'] = re.compile(r'\[(.*?)\]', re.U)
hn.C.regexes['parenthesis'] = re.compile(r'\[(.*?)\]')
hn.parse_full_name()
self.m(hn.first, "Benjamin", hn)
self.m(hn.last, "Franklin", hn)
Expand Down Expand Up @@ -193,7 +193,7 @@ def test_ambiguous_suffix_acronym_in_extra_delimiter_stays_nickname(self) -> Non
# handle_match() is applied uniformly regardless of which delimiter
# matched, not just the three built-ins.
hn = HumanName("JEFFREY {JD} BRICKEN", constants=None)
hn.C.extra_nickname_delimiters['curly_braces'] = re.compile(r'\{(.*?)\}', re.U)
hn.C.extra_nickname_delimiters['curly_braces'] = re.compile(r'\{(.*?)\}')
hn.parse_full_name()
self.m(hn.nickname, "JD", hn)
self.m(hn.suffix, "", hn)
Expand Down
4 changes: 2 additions & 2 deletions tests/test_python_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ def test_override_constants(self) -> None:
self.assertIs(hn.C, C)

def test_override_regex(self) -> None:
var = TupleManager([("spaces", re.compile(r"\s+", re.U)),])
var = TupleManager([("spaces", re.compile(r"\s+")),])
C = Constants(regexes=var)
hn = HumanName(constants=C)
self.assertTrue(hn.C.regexes == var)
Expand Down Expand Up @@ -340,7 +340,7 @@ def test_override_conjunctions(self) -> None:
self.assertTrue(sorted(hn.C.conjunctions) == sorted(var))

def test_override_capitalization_exceptions(self) -> None:
var = TupleManager([("spaces", re.compile(r"\s+", re.U)),])
var = TupleManager([("spaces", re.compile(r"\s+")),])
C = Constants(capitalization_exceptions=var)
hn = HumanName(constants=C)
self.assertTrue(hn.C.capitalization_exceptions == var)