为什么这个python Lark 语法这么慢?

问题描述

我正在尝试解析“ypcat -k netgroup”的输出 输出看起来像这种格式的多行:

group1 (host1,user1,domain1) (host2,user2,domain2) (host3,user3,domain3) ...

有时

group2 groupa groupb groupc ...

我第一次尝试使用这种百灵鸟语法:

def getNetgroups():
  parser = Lark(ypcat_grammer)
  res = subprocess.check_output(['ypcat -k netgroup'],shell=True).decode('utf-8')
  print(parser.parse(res).pretty())

ypcat_grammer = r"""
  ?start: _line+
  _line: groupname members NEWLINE
  members: (member|groupname)*
  member: "(" hostname? "," username? "," domainname? ")"
  
  username: _name
  domainname: _name
  groupname: _name
  hostname: _name
  _name: /([a-zA-Z0-9_\.\-]+)/
  %import common.WS_INLINE
  %import common.NUMBER
  %import common.NEWLINE
  %ignore WS_INLINE
"""

解析 4000 行需要 60 秒!!? 这似乎很长,所以我写了一个手工编码的解析器:

member = re.compile('\(([^,]*),([^,]*)\)')

def parseNetGroups():
  res = subprocess.check_output(['ypcat -k netgroup'],shell=True).decode('utf-8')
  rows = []
  for line in res.split('\n'):
    words = re.split('\s+',line)
    groupname = words.pop(0)
    members = []
    for word in words:
      if m:=member.match(word):
        members.append((m.group(1),m.group(2),m.group(3)))
      else:
        members.append(word)
    rows.append({'GROUPNAME':groupname,'MEMBERS':members})
  return pd.DataFrame(rows)

这花了 0.8 秒。 我做错了什么?

解决方法

更改为 parser='lalr' 将运行时间缩短至 3.8 秒。 这对我来说已经足够了。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...