让我们说,我有一个字符串:
s = "Hello, stack exchange. Let's solve my query"
让我们说我有3个子串
s1 = "solve"
s2 = "stack"
s3 = "Not present"
是否有快捷方式确定哪个子字符串首先出现在s?
我知道,我可以编写一个可以找到索引索引的函数,可能在字典中存储substr-index对,然后比较所有非负索引,但有没有更短的方式或pythonic方式这样做?
答案 0 :(得分:4)
使用正则表达式获得此功能的另一种方法是:
import re
s = "Hello, stack exchange. Let's solve my query"
s1 = "solve"
s2 = "stack"
s3 = "Not present"
r1 = re.compile('|'.join([s1,s2,s3]))
r1.findall(s)
这将返回如下列表:
['stack', 'solve']
从列表索引中可以得到首先出现的搜索字符串。
答案 1 :(得分:2)
您可以使用生成器查找所有位置,并使用min()
找到最左侧的位置:
positions = (s.find(sub), sub) for sub in (s1, s2, s3))
leftmost = min((pos, sub) for pos, sub in positions if pos > -1)[1]
这对每个子字符串只运行一次s.find()
,过滤掉不存在的任何子字符串。如果根本没有子串匹配,min()
将抛出ValueError
异常;你可能想要抓住它。
这会扫描字符串3次;如果测试的子串数量足够大,你需要构建一个trie structure,将索引循环到s
并测试该位置的字符是否存在于trie中:
def make_trie(*words):
root = {}
for word in words:
current = root
for letter in word:
current = current.setdefault(letter, {})
# insert sentinel at the end
current[None] = None
return root
def find_first(s, trie):
for i in range(len(s)):
pos, current, found = i, trie, []
while pos < len(s) and s[pos] in current:
found.append(s[pos])
current = current[s[pos]]
if None in current: # whole substring detected
return ''.join(found)
pos += 1
leftmost = find_first(s, make_trie(s1, s2, s3))
trie可以重复使用多个字符串。
答案 2 :(得分:1)
这是执行此操作的最短路径。 创建一个正则表达式,并使用re.search在第一次匹配时中断。
import re
inputs = ['solve','stack','Not present']
s = "Hello, stack exchange. Let's solve my query"
match = re.search(re.compile('|'.join(inputs)),s)
print(match.group())
#returns 'stack'
答案 3 :(得分:1)
你可以试试这个:
first_substr = min([(s.find(substr),substr) for substr in [s1, s2, s3] if s.find(substr)!=-1])[1]
由于