0

场景:

我有一个清单:

['item','place','thing']

我有一些字符串:

"item", "item1", "thing55", "place_C", "stuff", "junk5"

以上,我希望前四个匹配,后两个不匹配。startswith 函数最适合此检查。

(测试字符串“item”、“item1”等的列表不是python列表;它只是一组可能被检查的样本数据。但是,与“item”、“place”匹配的字符串列表"thing" 是代码中的 python 列表。)

我可以遍历第一个列表并将字符串与startswith进行比较:

successVar = False
for s in myStrings:
    if (testString.startswith(s)): 
        successVar = True
        break
#  Now you would check successVar to decide if string matched

但这并不一定在所有情况下都最有效。例如,假设这是 if/elif 结构的一部分:

if (testString == "hello"):
    # do something based on exact string match
elif (testString.endswith("!")):
    # do something if string ends with _one_ specific entity
elif <somehow, do the above comparison in here>
    # do something if string starts with any of the items in a list
else:
    # do something if string didn't match anything

我想我可以将整个检查包装在一个函数中,但我觉得可能有一种方法可以更轻松或更简洁地使用内联代码来做到这一点。

这甚至可以在不制作功能的情况下完成吗?

谢谢

4

4 回答 4

10

str.startswith()接受前缀元组:

>>> "item1".startswith(("item","place","thing"))
True
于 2013-09-11T17:10:29.823 回答
1

您可以将正则表达式用于各种测试。正则表达式很容易成为“开始于”、“结束于”、“完全匹配”或“包含”。您甚至可以指定匹配不区分大小写。您可以使用字典将正则表达式与要执行的每个操作相关联(应该是一个函数):

import re

def handle_item(text):
    print "handling item", text

def handle_place(text):
    print "handling place", text

def handle_thing(text):
    print "handling thing", text

match_dict = {"!$":          handle_thing,    # ends with !
              "(?i)^hello$": handle_place,    # case-insensitive exact match for hello
              "^@":          handle_item,     # begins with @
             }

test_string = raw_input("Enter a string to test: ")

for regex in match_dict:
    if re.search(test_string, regex):
        match_dict[regex](test_string)        # call function
        break

如果测试应该按特定顺序执行,您可以使用 acollections.OrderedDict来提供该顺序(或元组列表,就此而言)。另外,目前测试在找到一个匹配后停止;如果多个测试可以匹配,并且您希望它们都被处理,只需删除break.

当然,这只处理一个项目......我将它放在一个函数中并为每个项目调用它,将项目的拆分放在它自己的函数中。

于 2013-09-11T17:19:19.250 回答
0

可以csv用来分解你的字符串,然后将 a 传递tuplestr.startswith

import csv

check = ['item','place','thing']
items = '"item", "item1", "thing55", "place_C", "stuff", "junk5"'
match = [el for el in next(csv.reader([items], skipinitialspace=True)) if el.startswith(tuple(check))]
# ['item', 'item1', 'thing55', 'place_C']
于 2013-09-11T17:14:34.560 回答
0

将允许的前缀列表加入一个字符串,以 分隔|,例如:

pattern = "|".join(['item','place','thing'])

然后使用re.match()

strs = ["item", "item1", "thing55", "place_C", "stuff", "junk5"]
matching_strs = [s for s in strs if re.match(pattern, s)]

这会产生:

matching_strs
=> ['item', 'item1', 'thing55', 'place_C']

这也应该比建议的其他方法更快,因为它只会查看strs一次任何字符串,并将其与所有允许的前缀“一次”进行比较,而不是一次一个。

re.compile如果你使用on ,你甚至可以让它更快pattern

警告:这种简单的情况只有在允许的前缀不包含“特殊”字符(在re某种意义上)时才有效,例如|, .,(等。如果它们包含,您必须先将它们转义,然后再将它们与|.

于 2013-09-11T18:02:11.070 回答