Python在列表中查找字符串

时间:2015-05-21 20:25:44

标签: python regex

我有一个salt模块,它返回以下输出(我将所有这些存储到列表中以使迭代更容易):

    - 2015-05-21 19:25:08,060 [main] WARN  [::::::] c.p.core.FilteringPropertyPlaceholderConfigurer - Could not load properties from class path resource [proferi-component-test.properties]: class path resource [proferi-component-test.properties] cannot be opened because it does not exist
    - 2015-05-21 19:25:08,064 [main] WARN  [::::::] c.p.core.FilteringPropertyPlaceholderConfigurer - Could not load properties from class path resource [qe-prop-not-specified]: class path resource [qe-prop-not-specified] cannot be opened because it does not exist
    - 2015-05-21 19:25:13,290 [main] INFO  [::::::] c.p.a.m.persistence.modular.ModelSessionManager - Setup SessionManager modelSessionFactory
    - 2015-05-21 19:25:14,327 [main] INFO  [::::::] c.p.a.model.persistence.BlueprintsGraphReadSession - Loading model graph for application M-00000304-0000-0001-0000-000000000000 with version MV-0000000000002714-0000000000002695-true
    - 2015-05-21 19:25:14,658 [main] INFO  [::::::] c.p.a.m.p.hydration.AppModelGraphHydrator - AppModelGraph Hydration stats for app M-00000304-0000-0001-0000-000000000000 - total time:322ms | sql time:20ms | jackson mapping:32ms | vertex adding:6ms | core building:63ms | core population:15ms | proxying:84ms | invocation handler creation:80ms | interface list building:10ms | moving through result set:4ms | items processed:156
    - 2015-05-21 19:25:14,860 [main] INFO  [-:sales02:Session:SetPasswd:-:-:-] c.l.n.cluster.zookeeper.ZooKeeperClusterClient - Starting ClusterClient...
    - 2015-05-21 19:25:14,914 [main] INFO  [-:sales02:Session:SetPasswd:-:-:-] c.l.n.cluster.zookeeper.ZooKeeperClusterClient - Cluster started
    - 2015-05-21 19:25:14,915 [main] INFO  [-:sales02:Session:SetPasswd:-:-:-] com.proferi.core.NorbertProtobufServiceClient - Constructing NettyNetworkClient with close channel time -1 ms, max cnxns per node 10, stale request timeout 20 minutes, stale request purge frequency 2 minutes
    - 2015-05-21 19:25:14,961 [Thread-8] INFO  [-:sales02:Session:SetPasswd:-:-:-] c.l.n.c.zookeeper.ZooKeeperClusterManagerComponent - Connected to ZooKeeper
    - 2015-05-21 19:25:14,987 [Thread-8] INFO  [-:sales02:Session:SetPasswd:-:-:-] c.l.n.c.zookeeper.ZooKeeperClusterManagerComponent - Handling a Connected message
    - 2015-05-21 19:25:15,245 [main] INFO  [-:sales02:Session:SetPasswd:-:-:-] com.company.platform.cli.SetPassword - Password for email address john@tech.com for tenant sales02 was set
    - 2015-05-21 19:25:15,254 [main] INFO  [-:-:-:-:-:-:-] c.l.norbert.network.netty.NettyNetworkClient - Shutting down NetworkClient
    - 2015-05-21 19:25:15,273 [main] INFO  [-:-:-:-:-:-:-] c.l.norbert.network.netty.NettyNetworkClient - NetworkClient shut down
    - 2015-05-21 19:25:15,281 [main] INFO  [-:-:-:-:-:-:-] c.l.n.cluster.zookeeper.ZooKeeperClusterClient - Cluster shut down

从这个返回我想检查块是否有字符串

- 2015-05-21 19:05:18,108 [main] INFO  [-:sales02:Session:SetPasswd:-:-:-] com.company.platform.cli.SetPassword - Password for email address john@tech.com for tenant sales02 was set

这样做的最佳方式是什么?

我尝试使用for循环 -

for i in l:
    if s == i: # where s is the string above
        return True
    else:
        return False

但这个dint工作(返回False)。我尝试使用正则表达式,但字符串太复杂,我不能提出一个正则表达式公式。任何帮助将不胜感激。

由于这是一个列表,我知道我可以使用索引来获取所需的字符串,但我不想要字符串,我想在那里检查它,然后将自定义字符串返回给用户。

2 个答案:

答案 0 :(得分:5)

更简单的方法是使用以下内容:

if s in l:
    return True

不需要像这样的简单检查的for循环,它会遍历列表并返回正数(或者你想要返回的任何内容),如果它匹配匹配。它也是在python脚本中为CLI级菜单构建一些健壮性的一种方法。

提示:您可能希望将要检查的字符串列表更改为一组。运行速度稍快。

编辑:更好的方法:

return s in l

如果你已经开始使用for循环 -

for i in l:
   if any(i == s for i in entry)
        return True

虽然这可能是一个不太优雅的解决方案,但是使用any()确实允许你比上面的简单理解有一些更软的匹配 - 但是这有风险,因为如果列表中有一个字符串,那么至少你的匹配条件字符串,以及更多信息,它也将返回true。

答案 1 :(得分:1)

如果您正在寻找真正采用正则表达式的方法,您可以尝试以下方法。它可能不如简单地遍历列表那样有效,但它可以让您了解如何实现它。

虽然正则表达式的字面匹配很复杂(而且很混乱),但它允许您通过匹配组获取日志的每个组件。在真实环境中,您希望查看使用Grok过滤器的Logstash之类的内容(了解它们,它们非常有趣!)。

注意:以下正则表达式不是100%准确,可能需要在给定更多数据的情况下进行更改,但您明白了。

您想要的行的字面匹配看起来像:

-\s(\d{4}-\d{1,2}-\d{1,2})\s(\d{1,2}:\d{1,2}:\d{1,2},\d{1,3})\s(\[\w+\])\s(\w+)\s+(\[.*\])\s([a-zA-Z.]+)\s-\s(.*)

仅将邮件设为匹配组:

(?:.*)\s(([a-zA-Z_$][a-zA-Z\d_$]*\.)*([a-zA-Z_$][a-zA-Z\d_$]+)\s-\s)(.*)

例如,我不会使用列表,但只是为了演示一个字符串:

import re

logLine = "- 2015-05-21 19:05:18,108 [main] INFO  [-:sales02:Session:SetPasswd:-:-:-] com.company.platform.cli.SetPassword - Password for email address john@tech.com for tenant sales02 was set"
rx = "-\s(\d{4}-\d{1,2}-\d{1,2})\s(\d{1,2}:\d{1,2}:\d{1,2},\d{1,3})\s(\[\w+\])\s(\w+)\s+(\[.*\])\s([a-zA-Z.]+)\s-\s(.*)"

reMatch = re.match(rx, logLine)

if (reMatch):
    print reMatch.group(1)
    # Groups 1-7

您可以遍历匹配组,并且您会看到这样的日志行将为您提供:

  1. 2015-05-21
  2. 19:05:18,108
  3. [main]
  4. INFO
  5. [-:sales02:Session:SetPasswd:-:-:-]
  6. com.company.platform.cli.SetPassword
  7. Password for email address john@tech.com for tenant sales02 was set
  8. 那么您可以检查匹配组7以查看消息中您想要的字符串是否存在,或者只是与第二个正则表达式交替以仅检查一个组:

    reMatch2 = re.match(rx2, logLine)
    
    if (reMatch2):
        print reMatch2.group(1)
    

    您将使用缩短的正则表达式获得类似的结果,但它可能允许您在将来对日志执行更多操作,而不仅仅是确定某条线(或线本身)中是否存在某些内容需要。