3

I used re.findall to tokenize strings that not always have to be splitting after a word (a token can have compound words). I got the tokens in the described way. However, it is not keeping dots included in the regex pattern.

For instance, consider the following code:

import re
all_domain=['com edu','.com edu','inc.', '.com', 'inc', 'com', '.edu', 'edu']
all_domain.sort(key=len, reverse=True)
domain_alternators = '|'.join(all_domain)

print(domain_alternators)
regex = re.compile(r'\b({}|[a-z-A-Z]+)\b'.format(domain_alternators))
print(regex)
#re.compile('\\b(.com edu|com edu|inc.|.com|.edu|inc|com|edu|[a-z-A-Z]+)\\b')

name= 'BASIC SCHOOL DISTRICT .COM'
result=regex.findall(name.lower())

it should return as a result ['basic', 'school', 'district', '.com'] because .com has higher priority in the alternators (.com comes before com in the alternator lists):

.com edu|com edu|inc.|.com|.edu|inc|com|edu

How can I get ['basic', 'school', 'district', '.com'] instead of getting ['basic', 'school', 'district', 'com']

Thanks

John Barton
  • 1,581
  • 4
  • 25
  • 51
  • When you have a string like `.com` there is no `\b` before the `.`. From the docs: `\b is defined as the boundary between a \w and a \W character` – Mark Mar 11 '20 at 20:16

1 Answers1

1

You should:

Use

import re
all_domain=['com edu','.com edu','inc.', '.com', 'inc', 'com', '.edu', 'edu']
all_domain.sort(key=len, reverse=True)
domain_alternators = '|'.join(map(re.escape,all_domain)) # <-- HERE
regex = re.compile(r'(?<!\w)({}|[a-z-A-Z]+)(?!\w)'.format(domain_alternators))  # <-- HERE

name= 'BASIC SCHOOL DISTRICT .COM'
result=regex.findall(name.lower())
print(result) # => ['basic', 'school', 'district', '.com']

See the Python demo

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563