的Python:检查一个字符串的子串是否是另一个字符串的子串,条件在第一子串作为特定长度
我有两个字符串像这样:的Python:检查一个字符串的子串是否是另一个字符串的子串,条件在第一子串作为特定长度
23971500000239713000002344550000023971900000
和
23971500000239719000002344550000023971600000
我想测试第一个字符串中是否存在至少一个长度为10或更多的子字符串也在第二个子字符串中。所以逻辑应该评估为真,因为
23971500000
在两个字符串中。
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))
究竟是什么downvote? – 2014-10-22 00:21:01
你改进了代码,但它仍然只生成len'10'的子集不多! – Kasramvd 2014-10-22 00:25:16
@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
所以我的错误是,子串必须被分块为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]
您需要编写更多的代码来删除以前匹配后缀的匹配项。
我认为它应该评估为false,因为3971300000存在于第一个字符串中,但不存在于第二个 – wim 2014-10-22 00:13:03
对不起,我希望它评估为真,如果至少存在一个长度共同的十个子字符串。 – robertevansanders 2014-10-22 00:14:55
我不认为第二部分是明确的。将会有多种方法去除通用元素,导致不同的输出 – wim 2014-10-22 00:16:39