I am trying to make sure that spacy treats dot as a separate token except when it is between two digits. I noticed nlp.Defaults.infixes uses lookaround operators extensively, so I followed the example:
infixes = nlp.Defaults.infixes + (r'''[;,:]''',
r'(?<=[a-zA-Z_])[\.^]', r'[\.^](?=[a-zA-Z_])',
)
infix_regex = spacy.util.compile_infix_regex(infixes)
nlp.tokenizer.infix_finditer = infix_regex.finditer
Now upper case behaves as expected:
list(nlp.tokenizer('HELLO.WORLD'))
[HELLO, ., WORLD]
But if right-hand side is lowercase, it fails:
list(nlp.tokenizer('HELLO.world'))
[HELLO.world]
list(nlp.tokenizer('hello.world'))
[hello.world]
list(nlp.tokenizer('hello.WORLD'))
[hello, ., WORLD]
Another example, where a regex finds parentheses but not slashes:
infixes = nlp.Defaults.infixes + (r'(?<=[a-zA-Z_])[\.\(\)/](?=[a-zA-Z_])', )
infix_regex = spacy.util.compile_infix_regex(infixes)
nlp.tokenizer.infix_finditer = infix_regex.finditer
tests = [
'mid(inferior',
'mid/inferior',
'left.mid',
'left.mid/inferior']
pattern = re.compile(r'(?<=[a-zA-Z_])[\.\(\)/](?=[a-zA-Z_])')
for tt in tests:
print("-"*20)
print(pattern.split(tt))
print(list(nlp.tokenizer(tt)))
result:
--------------------
['mid', 'inferior']
[mid, (, inferior]
--------------------
['mid', 'inferior']
[mid, /, inferior]
--------------------
['left', 'mid']
[left.mid]
--------------------
['left', 'mid', 'inferior']
[left.mid/inferior]
As one can see, for some reason within spacy, the regex pattern does not split on dot, and if word is not purely alphabetic, it fails to split on slash, even though that should not be an issue for the above regex