【问题标题】:count occurrences of a string pattern in a file and count计算文件中字符串模式的出现次数并计数
【发布时间】:2020-10-06 04:17:29
【问题描述】:

团队,

我正在尝试计算文件中的两个模式并将它们列为

pattern1: 2
pattern2: 3
#!/usr/bin/python
import os
import re

d = dict()
with open('/home/user/waste/nodes-prod.log', 'r') as file:
    for line in file:
        line = line.strip()
        for word in line.split():
            node1 = re.match(r"team1.*", word)
            type(node1)
            node2 = re.match(r"team2.*", word)
            type(node2)
            if node1 in d:
                d[node1] = d[node1] + 1
            else:
                d[node2] = d[node2] + 1
for key in list(d.keys()):
    print(key, ":", d[key]) 

下面是我的/home/user/waste/nodes-prod.log

cat /home/user/waste/nodes-prod.log
team1-develop
team1-work
team2-research1
team2-research2
team2-research3

输出

Traceback (most recent call last):
  File "read-and-count-words-pattern-fromfile-using-dict-in-python.py", line 17, in <module>
    d[node2] = d[node2] + 1
KeyError: <_sre.SRE_Match object; span=(0, 10), match='team2-research1'>

预期:

node1: 2
node2: 3

【问题讨论】:

    标签: python-3.x regex regex-group


    【解决方案1】:

    如果你将整个文本读入内存会更容易(如果考虑到文件的大小这不是负担的话):

    import re 
    
    with open(fn) as f:
        txt=f.read()
        
    print(f'node 1: {len(re.findall(r"team1.*", txt))}')    
    print(f'node 2: {len(re.findall(r"team2.*", txt))}')
    

    打印:

    node 1: 2
    node 2: 3
    

    如果你确实想逐行做,你可以保留一个计数器:

    import re 
    
    node1,node2 =(0,0)
    with open(fn) as f:
        for line in f:
            if re.search(r"team1.*", line): node1+=1 
            if re.search(r"team2.*", line): node2+=1 
        
    print(f'node 1: {node1}')   
    print(f'node 2: {node2}')
    

    更好的是,您可以使用 dict 将任何 `"team\d" 映射到该变量号的映射:

    nodes={}
    with open(fn) as f:
        for line in f:
            if m:=re.search(r"team(\d+).*", line): 
                nodes[m.group(1)]=nodes.get(m.group(1),0)+1
    
    >>> nodes
    {'1': 2, '2': 3}
    

    【讨论】:

      【解决方案2】:
      #!/usr/bin/python
      import os
      import re
      
      # dict is the dictionary,
      # pattern is the regular expression,
      # word is the word to match.
      def increment(dict: dict, pattern: str, word: str):
          match = re.match(pattern, word)
          if match:
              # re.match returns a Match object, not a string.
              # .group(n) returns n-s capture. .group() returns
              # 0th capture, i.e. the whole match:
              node = match.group()
              # Initialise the counter, if necessary:
              if not node in dict:
                  dict[node] = 0
              # Increment the counter:
              dict[node] += 1
      
      # filename is a string that contains a path to file to parse,
      # patterns is a dictionary of patterns to check against,
      # the function returns a dictionary.
      def scores(filename: str, patterns: dict) -> dict:
          # Initialise the dictionary that keeps counters:
          d = dict()
          with open(filename, 'r') as file:
              for line in file:
                  line = line.strip()
                  for word in line.split():
                      # Check against all patterns:
                      for pattern in patterns:
                          increment(d, pattern, word)
          return d
      
      # Patterns to search for.
      # It is claimed that Python caches the compiled
      # regular expressions, so that we don't need
      # to pre-compile them:
      patterns = [r"team1.*", r"team2.*"]
      
      # file to parse:
      filename = '/home/user/waste/nodes-prod.log'
      
      # This is how a dictionary is iterated, when both key and value are needed:
      for key, value in scores(filename, patterns).items():
          print(key, ":", value)
      
      • def increment(dict: dict, pattern: str, word: str): 定义了一个函数,它接收字典 dictpatternword 以检查 patern。和一个匹配对象match。参数是类型化的,在 Python 中是可选的。
      • def scores(filename: str, patterns: dict) -&gt; dict: 定义了一个函数,该函数接收 filename 作为字符串、patterns 的字典并返回另一个匹配计数字典。

      【讨论】:

      • 你能给我解释一下你的代码吗?特别是什么是组关键字?
      • @AhmFM 请阅读更新后的答案。我改进了代码并添加了更多的 cmets,包括对 groups() 的解释。
      猜你喜欢
      • 1970-01-01
      • 2021-12-16
      • 2016-04-28
      • 1970-01-01
      • 1970-01-01
      • 2012-06-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多