的Python:检查一个字符串的子串是否是另一个字符串的子串,条件在第一子串作为特定长度

问题描述:

我有两个字符串像这样:的Python:检查一个字符串的子串是否是另一个字符串的子串,条件在第一子串作为特定长度

23971500000239713000002344550000023971900000 

23971500000239719000002344550000023971600000 

我想测试第一个字符串中是否存在至少一个长度为10或更多的子字符串也在第二个子字符串中。所以逻辑应该评估为真,因为

23971500000在两个字符串中。

+0

我认为它应该评估为false,因为3971300000存在于第一个字符串中,但不存在于第二个 – wim 2014-10-22 00:13:03

+0

对不起,我希望它评估为真,如果至少存在一个长度共同的十个子字符串。 – robertevansanders 2014-10-22 00:14:55

+2

我不认为第二部分是明确的。将会有多种方法去除通用元素,导致不同的输出 – wim 2014-10-22 00:16:39

s1 = "23971500000239713000002344550000023971900000" 

s2 = "23971500000239719000002344550000023971600000" 

test = (s1[x:x+10] for x in xrange(len(s1)-9)) 
print(any(x in s2 for x in test)) 
+0

究竟是什么downvote? – 2014-10-22 00:21:01

+0

你改进了代码,但它仍然只生成len'10'的子集不多! – Kasramvd 2014-10-22 00:25:16

+0

@Kasra如果没有长度为10的子字符串,那么将不会有11或更长的子字符串 – 2014-10-22 00:26:53

>>> s1 = '23971500000239713000002344550000023971900000' 
>>> s2 = '23971500000239719000002344550000023971600000' 
>>> minlen = 10 

>>> subs = (s1[ii:ii+minlen] for ii in range(len(s1) - minlen + 1)) 
>>> any(sub in s2 for sub in subs) 
True 

也就是说,产生最小长度的所有可能的子中的一个字符串,并检查它们是否在另一个字符串。

当然,如果你有非常长的字符串(参见Boyer-Moore获取灵感),还有更高效的解决方案,但上面的内容似乎是按照你想要的而且非常简单。

str1 = "23971500000239713000002344550000023971900000" 
str2 = "23971500000239719000002344550000023971600000" 

def subsearch(str1, str2): 
    for i in range(len(str1)-9): 
     if str1[i:10+i:] in str2: 
      return True 
    return False 

print subsearch(str1, str2) 
>>True 
+0

所以我的错误是,子串必须被分块为11,0:10,11:22等块...所以我想搜索在第一个字符串的四个块中。并非每一个可能的子字符串。我试图修改这个,但有困难。 – robertevansanders 2014-10-22 00:24:02

s1 = '23971500000239713000002344550000023971900000' 
s2 = '23971500000239719000002344550000023971600000' 

def find_all_substrings(s): 
    return [ s[i:i+10] for i in range(len(s)) if len(s[i:i+10]) == 10 ] 

common_substrings = [s for s in find_all_substrings(s1) if s in s2] 

你的问题是模糊的,一旦你已经决定,有一个共同的字符串。但条件成立时len(common_strings) > 0

为了完整起见,下面是正则表达式中的一个解决方案,以显示可能性。

我不建议在生产代码中使用此解决方案。

import re 

s1 = "23971500000239713000002344550000023971900000" 
s2 = "23971500000239719000002344550000023971600000" 

# Since both strings contain only digits, ~ can be safely used as separator 
s = s1 + '~' + s2 

找到匹配:

re.match(r'^\d*?(\d{10,})\d*~\d*\1', s) 

查找某个索引的所有最长匹配:

r = re.compile(r'(\d{10,})\d*~\d*\1') 
o = [r.match(s, i) for i in range(0, len(s1))] 

# Print result 
print([i.group(1) if i else None for i in o]) 

输出的例子:

['2397150000023971', '397150000023971', '97150000023971', '7150000023971', '150000023971', '50000023971', '0000023971', None, None, None, None, None, None, None, None, None, None, '000002344550000023971', '00002344550000023971', '0002344550000023971', '002344550000023971', '02344550000023971', '2344550000023971', '344550000023971', '44550000023971', '4550000023971', '550000023971', '50000023971900000', '0000023971900000', '000023971900000', '00023971900000', '0023971900000', '023971900000', '23971900000', '3971900000', None, None, None, None, None, None, None, None, None]

您需要编写更多的代码来删除以前匹配后缀的匹配项。