Python 如果多个子字符串按特定顺序匹配字符串

Python 如果多个子字符串按特定顺序匹配字符串,python,Python,我想知道如何检测两个子字符串是否以特定顺序匹配主字符串。例如,如果我们在字符串中的任何位置查找“hours”,然后查找“minutes”,并且字符串是“what is 5 hours in minutes”,它将返回true。如果字符串是“what is 5 minutes in hours”,那么如果索引(a)True@padraiccnningham它包含空字符串。什么空字符串?我通过了nothing@PadraicCunningham函数回答“此字符串是否按顺序包含给定的单词?”。你什么也

我想知道如何检测两个子字符串是否以特定顺序匹配主字符串。例如,如果我们在字符串中的任何位置查找
“hours”
,然后查找
“minutes”
,并且字符串是
“what is 5 hours in minutes”
,它将返回
true
。如果字符串是
“what is 5 minutes in hours”
,那么如果索引(a)false
 if index(a) < index(b):
    True
 else:
    This
真的 其他: 这 使用索引方法确定哪一个先到。if语句给出了一个条件,一旦你发现哪个先到,你会做什么。你明白我想说什么吗

s = "what is 5 hours in minutes"
a, b = s.find("hours"),s.find("minutes")
print(-1 < a < b)
将匹配:

"foobar"
但它们不是字符串中的实际单词。如果要匹配实际单词,则需要拆分和清理文本,或者使用正则表达式来设置单词边界

如果要匹配精确的单词而不是部分匹配,请使用正则表达式并使用单词边界:

import re


def consec(s, *args):
    if not args:
        raise ValueError("args cannot be empty")
    it = iter(args)
    prev = re.search(r"\b{}\b".format(next(it)), s)
    if not prev:
        return False
    prev = prev.end() 
    for w in args:
        ind = re.search(r"\b{}\b".format(w), s, prev + 1)
        if not ind:
            return False
        prev = ind.end() 
    return True
哪个与foobar中的“foo”和“bar”不匹配:

In [9]: consec("foobar","foo","bar")
Out[9]: False

In [10]: consec("foobar bar for bar","foo","bar")
Out[10]: False

In [11]: consec("foobar bar foo bar","foo","bar")
Out[11]: True

In [12]: consec("foobar","foo","bar")
Out[12]: False

In [13]: consec("foobar bar foo bar","foo","bar")
Out[13]: True

In [14]: consec("","foo","bar")
Out[14]: False

In [15]: consec("foobar bar foo bar","foobar","foo","bar")
Out[15]: True

这将适用于任何一组单词和任何字符串:

def containsInOrder(s, *words):
    last = -1
    for word in words:
        last = s.find(word, last + 1)
        if last == -1:
            return False
    return True
这样使用:

>>> s = 'what is 5 hours in minutes'
>>> containsInOrder(s, 'hours', 'minutes')
True
>>> containsInOrder(s, 'minutes', 'hours')
False
>>> containsInOrder(s, '5', 'hours', 'minutes')
True
>>> containsInOrder('minutes hours minutes', 'hours', 'minutes')
True
>>> containsInOrder('minutes hours minutes', 'minutes', 'hours')
True

您可以使用一个正则表达式,例如“hours.*minutes”,也可以使用一个简单的字符串搜索来查找“hours”,注意找到它的位置,然后从该位置开始另一次搜索“minutes”。

正则表达式在这里可以很好地工作。正则表达式r“hours.*minutes”表示查找后跟小时的字符,但后面跟分钟的字符不能超过0个。另外,请确保使用正则表达式库中的
搜索
函数,而不是
匹配
,因为匹配从字符串的开头开始检查

import re
true_state ="what is 5 hours in minutes"
false_state = "what is 5 minutes in hours"
pat = re.compile(r"hours.*minutes")
statements = [true_state, false_state]
for state in statements:
    ans= re.search(pat, state)
    if ans:
        print state
        print ans.group()
输出
正则表达式
/hours.*minutes/
?如果需要单词边界,请使用“\b”\bhours\b.*\bminutes\b”这对字符串“minutes-hours-minutes”不起作用,其中“hours”确实出现在“minutes”之前。您需要从位置
a+1
开始搜索“分钟数”@MathiasRav,我会让OP来决定什么,但如果需要,那么这是一个简单的修复方法。@ShaneSmiskol请记住@MathiasRav的评论。如果您的字符串是
'minutes'
@Kupiakos,则返回
false
。@ShaneSmiskol我的答案处理了这个问题。它还处理任意数量的单词。
containsInOrder(“foo”)->True
@padraiccnningham它包含空字符串。什么空字符串?我通过了nothing@PadraicCunningham函数回答“此字符串是否按顺序包含给定的单词?”。你什么也没给。所有字符串都不包含任何内容。因此,它是
真的
def containsInOrder(s, *words):
    last = -1
    for word in words:
        last = s.find(word, last + 1)
        if last == -1:
            return False
    return True
>>> s = 'what is 5 hours in minutes'
>>> containsInOrder(s, 'hours', 'minutes')
True
>>> containsInOrder(s, 'minutes', 'hours')
False
>>> containsInOrder(s, '5', 'hours', 'minutes')
True
>>> containsInOrder('minutes hours minutes', 'hours', 'minutes')
True
>>> containsInOrder('minutes hours minutes', 'minutes', 'hours')
True
import re
true_state ="what is 5 hours in minutes"
false_state = "what is 5 minutes in hours"
pat = re.compile(r"hours.*minutes")
statements = [true_state, false_state]
for state in statements:
    ans= re.search(pat, state)
    if ans:
        print state
        print ans.group()
what is 5 hours in minutes
hours in minutes