在电子邮件前缀中查找所有部分匹配

时间:2014-07-22 02:17:48

标签: python regex

鉴于姓名和电子邮件ID,我想查找该名称的任何前缀(应该以第一个字符开头并且可以延伸到'n'字符)是否在电子邮件中

Name = "mohan". Possible prefixes : 'm','mo','moh','moha', 'mohan'
1) email = "mohanabc"   : Matched till mohan so match count is 5
2) email = 'abcmohacde' : Again Matched till 'moha', so match count it 4
3) email = 'mohabc'     : Match count is 4
4) email = 'nahom'      : Match count 0
5) email = 'ohan'       : Should return match count 0. Looking for the prefix of that name.

我正在使用python,因此非常感谢任何特定于python的解决方案。但我很高兴得到任何其他基于正则表达式的解决方案(好的python接受一般正则表达式,所以不应该是一个问题)。

一个天真的解决方案是将所有前缀添加到正则表达式并匹配电子邮件。但我正在寻找特定的东西。

2 个答案:

答案 0 :(得分:2)

对于这类事情,我可能会建议在 regexes 尝试(数据结构),特别是对于较大的数据集。

尝试 Python 实现,它是 marisa-trie C ++库的包装。

https://github.com/kmike/marisa-trie

他们描述了其性能特征如下:

  

MARISA-trie中的字符串数据可能比内存少50x-100x   在标准的Python词典中;原始查找速度可比;特里   还提供快速高级方法,如前缀搜索。

它可以让你做这样的事情:

  

查找此trie中以给定前缀开头的所有项目:

>> trie.items(u'fo')
[(u'foo', (1, 2)), (u'foo', (2, 1), (u'foobar', (3, 3))]

答案 1 :(得分:2)

使用此:

m(?:o(?:h(?:a(?:n)?)?)?)?

潜在前缀的数量是匹配的长度。

the regex demo中,请参阅右侧窗格中的捕获组。

<强>解释

  • m必须匹配
  • 非捕获组(?:o ... )?是可选的
  • 非捕获组(?:h ... )?是可选的
  • 非捕获组(?:a ... )?是可选的
  • 非捕获组(?:n)?是可选的

在Python中:

我们检索所有比赛并花费最长时间。此处,字符串abcmohmohaabc包含mohmoha

subject = "abcmohmohaabc"
matches = re.findall("m(?:o(?:h(?:a(?:n)?)?)?)?", subject)
print("Matches: ", matches)
longest = sorted(matches)[-1]
print("Longest: ",  longest )
print( len(longest) )
for i in range(1, 1+len(longest)):
    print(longest[:i])

<强>输出

Matches:  ['moh', 'moha']
Longest:  moha
4
m
mo
moh
moha

特例:Sought String中的内部重复

请注意,如果搜索到的字符串内部重复了第一个字符(例如,如果我们搜索的是mohan,而不是搜索momohan,那么momomohan就会出现(?=(m(?:o(?:m(?:o(?:h(?:a(?:n)?)?)?)?)?)?))这样的字符串在这是一个问题,我们可以将正则表达式包装在一个捕获组中,并将捕获组包装在前瞻中,允许重叠匹配:subject = "ABmomomohanABmomohCD" matches = re.findall("(?=(m(?:o(?:m(?:o(?:h(?:a(?:n)?)?)?)?)?)?))", subject) print("Matches: ", matches) longest = sorted(matches)[-1] print("Longest: ", longest ) print( len(longest) ) for i in range(1, 1+len(longest)): print(longest[:i]) 。代码将是相同的。

Matches:  ['momo', 'momohan', 'mo', 'momoh', 'mo']
Longest:  momohan
7
m
mo
mom
momo
momoh
momoha
momohan

# NOTE: in the ABmomomohanABmomohCD input string, the five matches are found 
# at the following starting positions:
#   ABmomomohanABmomohCD
#   1:mo
#     2:momohan
#       3:mo
#              4:momoh
#                5:mo 

<强>输出:

name = "mohan"
theregex = "(?=(" + name[0]
for c in name[1:]:
    theregex += "(?:" + c
for c in name[1:]:
    theregex += ")?"
theregex += "))"
print(theregex)    

动态生成正则表达式

这是一种方式:

(?=(m(?:o(?:h(?:a(?:n)?)?)?)?))

输出:

{{1}}