【问题标题】:Python find string in listPython在列表中查找字符串
【发布时间】:2015-08-03 17:01:48
【问题描述】:

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

    - 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

但是这很有效(返回 False )。我尝试使用正则表达式,但字符串太复杂,我无法想出正则表达式公式。任何帮助将不胜感激。

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

【问题讨论】:

  • 什么意思?从不返回 True?
  • 我编辑了那部分。它返回错误
  • 为什么不检查一些独特的关键字?您是否正在尝试为您的目标字符串找到 100% 匹配?

标签: python regex


【解决方案1】:

一个更简单的方法是使用类似的东西:

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。

【讨论】:

  • 我确实尝试过,但它不起作用。我认为这是因为第一个元素将返回 False 并且存在该函数。
  • @letsc 我刚刚看到你评论说它不起作用,然后在两秒钟后接受答案。嗯?
  • 逻辑是对的,我这边执行有错误。
【解决方案2】:

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

虽然正则表达式的文字匹配很复杂(而且混乱),但它允许您通过匹配组来获取日志的每个组成部分。在真实环境中,您可能想看看像 Logstash 这样使用 Grok 过滤器的东西(学习它们,它们很有趣!)。

注意:以下正则表达式并非 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

那么您可以检查匹配组 7 以查看消息中所需的字符串是否存在,或者简单地与第二个正则表达式交替以仅检查一个组:

reMatch2 = re.match(rx2, logLine)

if (reMatch2):
    print reMatch2.group(1)

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

【讨论】:

    猜你喜欢
    • 2023-04-03
    • 2011-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多