我不太擅长解析文件,但有一些我想完成的事情。 下面是具有一些 require 语句的 .lua 脚本片段。 我想使用 Python 解析这个.lua文件并提取"require"语句。
例如,下面是 require 语句:
require "common.acme_1"
require "common.acme_2"
require "acme_3"
require "common.core.acme_4"
从上面的示例中,我想从所需的文件中拆分目录。 在示例中"需要"common.acme_1",目录将是通用的,所需的文件将是acme_1。 然后,我将.lua扩展添加到acme_1。 我需要这些信息,以便我可以验证文件是否存在于文件系统上(我知道该怎么做),然后针对luac(编译器)以确保它是一个有效的lua文件(我也知道如何做)。
我只需要帮助使用 Python 将这些 require 语句拉出并将目录名称与文件名分开。
您可以使用内置字符串方法执行此操作,但由于解析有点复杂(路径可以是多部分),最简单的解决方案可能是使用正则表达式。 如果您使用的是正则表达式,则可以使用组进行解析和拆分:
import re
data =
'''
require "common.acme_1"
require "common.acme_2"
require "acme_3"
require "common.core.acme_4"
'''
finds = re.findall(r'requires+"(([^."]+.)*)?([^."]+)"', data, re.MULTILINE)
print [dict(path=x[0].rstrip('.'),file=x[2]) for x in finds]
第一组是路径(包括尾随的.),第二组是匹配重复路径部分所需的内部组(丢弃),第三组是文件名。 如果没有路径,你会得到path=''
.
输出:
[{'path': 'common', 'file': 'acme_1'}, {'path': 'common', 'file': 'acme_2'}, {'path': '', 'file': 'acme_3'}, {'path': 'common.core', 'file': 'acme_4'}]
来吧!
import sys
import os.path
if len(sys.argv) != 2:
print "Usage:", sys.argv[0], "<inputfile.lua>"
exit()
f = open(sys.argv[1], "r")
lines = f.readlines()
f.close()
for line in lines:
if line.startswith("require "):
path = line.replace('require "', '').replace('"', '').replace("n", '').replace(".", "/") + ".lua"
fName = os.path.basename(path)
path = path.replace(fName, "")
print "File: " + fName
print "Directory: " + path
#do what you want to each file & path here
这是一个疯狂的单行,不确定这是否正是你想要的,而且肯定不是最理想的......
In [270]: import re
In [271]: [[s[::-1] for s in rec[::-1].split(".", 1)][::-1] for rec in re.findall(r"require "([^"]*)", text)]
Out[271]:
[['common', 'acme_1'],
['common', 'acme_2'],
['acme_3'],
['common.core', 'acme_4']]
这是直截了当的
一个衬里很棒,但它们需要花费太多精力才能尽早理解,在我看来这不是使用正则表达式的工作
mylines = [line.split('require')[-1] for line in open(mylua.lua).readlines() if line.startswith('require')]
paths = []
for line in mylines:
if 'common.' in line:
paths.append('common, line.split('common.')[-1]
else:
paths.append('',line)
你可以使用 finditer:
lua='''
require "common.acme_1"
require "common.acme_2"
require "acme_3"
require 'common.core.acme_4'
'''
import re
print [m.group(2) for m in re.finditer(r'^requires+('|")([^'"]+)(1)', lua, re.S | re.M)]
# ['common.acme_1', 'common.acme_2', 'acme_3', 'common.core.acme_4']
然后只需在"."上拆分即可拆分为路径:
for e in [m.group(2) for m in re.finditer(r'^requires+('|")([^'"]+)(1)', lua, re.S | re.M)]:
parts=e.split('.')
if parts[:-1]:
print '/'.join(parts[:-1]), parts[-1]
else:
print parts[0]
指纹:
common acme_1
common acme_2
acme_3
common/core acme_4
file = '/path/to/test.lua'
def parse():
with open(file, 'r') as f:
requires = [line.split()[1].strip('"') for line in f.readlines() if line.startswith('require ')]
for r in requires:
filename = r.replace('.', '/') + '.lua'
print(filename)
with 语句将打开有问题的文件。 下一行创建以"require"开头的所有行的列表并拆分它们,忽略"require"并仅抓取最后一部分并去除双引号。 然后浏览列表并用斜杠替换点并附加".lua"。 打印语句显示结果。