使用 findall 的交流发电机中的字符串不匹配正确的字符串

String not matching correct string in alternators using findall

我使用 re.findall 来标记字符串,这些字符串不必总是在单词后拆分(标记可以包含复合词)。我以描述的方式获得了令牌。但是,它不保留正则表达式模式中包含的点。

例如,考虑以下代码:

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())

结果应该 return ['basic', 'school', 'district', '.com'] 因为 .com 在交流发电机中具有更高的优先级(.com 在交流发电机列表中排在 com 之前):

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

如何获得 ['basic', 'school', 'district', '.com'] 而不是 ['basic', 'school', 'district', 'com']

谢谢

你应该:

  • 转义替代项以便 . 可以匹配一个点(即使用 '|'.join(map(re.escape,all_domain))
  • 使用明确的单词边界,左手 (?<!\w) 和右手 (?!\w),因为 \b 的意思是上下文相关的,参见 Regular Expression Word Boundary and Special Characters and regex to match word boundary beginning with special characters 并且有一个还有很多这样的问题。

使用

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']

Python demo