我是一名Perl程序员,他试图通过我之前完成的一些工作并将其转换为Python来学习Python.这不是逐行翻译.我想学习Python技术来完成这类任务.
我正在解析Windows INI文件.部分名称采用以下格式:
[<type> <description>]
Run Code Online (Sandbox Code Playgroud)
这<type>是一个单词字段,不区分大小写.在<description>可能是多个单词.
在一节之后,有一堆参数和值.这些是以下形式:
<parameter> = <value>
Run Code Online (Sandbox Code Playgroud)
参数没有空格,只能包含下划线,字母和数字(不区分大小写).因此,第一个=是参数和值之间的分隔符.在等号周围可能存在将参数和值分开的空白区域.在行的开头或结尾可能有额外的空白区域.
在Perl中,我使用正则表达式进行解析:
while (my $line = <CONTROL_FILE>) {
chomp($line);
next if ($line =~ /^\s*[#;']/); #Comments start with "#", ";", or "'"
next if ($line =~ /^\s*$/); #Ignore blank lines
if ($line =~ /^\s*\[\s*(\w+)\s+(.*)/) { #Section
say "This is a '$1' section called '$2'";
}
elsif ($line =~ /^\s*(\w+)\s*=\s*(.*)/) { #Parameter
say "Parameter is '$1' with a value of '$2'";
}
else { #Not Comment, Section, or Parameter
say "Invalid line";
}
}
Run Code Online (Sandbox Code Playgroud)
问题是我被Perl破坏了,所以我认为最简单的方法就是使用正则表达式.这是我到目前为止的代码......
for line in file_handle:
line = line.strip
# Comment lines and blank lines
if line.find("#") == 1 \
or line.find(";") == 1 \
or line.whitespace:
continue
# Found a Section Heading
if line.find("[") == 1:
print "I want to use a regular expression here"
print "to split the section up into two pieces"
elif line.find("=") != -1:
print "I want to use a regular expression here"
print "to split the parameter into key and value"
else
print "Invalid Line"
Run Code Online (Sandbox Code Playgroud)
这里有几件令我恼火的事情:
我一直在阅读各种在线教程,他们帮助我理解语法,但对处理语言本身的方式并不多 - 特别是那些倾向于用另一种语言思考的人.
我的问题:
Python包含一个ini解析库.如果你想构建一个库来解析ini文件,那么你正在寻找一个真正的解析器.正则表达式不会削减它,使用PLY或钩在flex/bison C解析器中.还可以使用其他python解析资源.
Lexers会为您处理所有文本消耗和树构造,因为它是一个容易出现程序员错误的机械任务.IE本节:
while (my $line = <CONTROL_FILE>) {
chomp($line);
next if ($line =~ /^\s*[#;']/); #Comments start with "#", ";", or "'"
next if ($line =~ /^\s*$/); #Ignore blank lines
if ($line =~ /^\s*\[\s*(\w+)\s+(.*)/) { #Section
say "This is a '$1' section called '$2'";
}
elsif ($line =~ /^\s*(\w+)\s*=\s*(.*)/) { #Parameter
say "Parameter is '$1' with a value of '$2'";
}
else { #Not Comment, Section, or Parameter
say "Invalid line";
}
}
Run Code Online (Sandbox Code Playgroud)
由词法分析器创建,您只需要定义正确的正则表达式.解析器从词法分析器中提取标记,并确定它们是否适合允许的标记模式.那是:
[<type> <description>]
<parameter> = <value>
Run Code Online (Sandbox Code Playgroud)
定义这些令牌,然后定义如何适合.其他所有东西都融合在一起.对于那些认为你可以通过快速循环和一些正则表达式做得更好的人,我建议你阅读Lex&Yacc,第二版.
对于我用PLY写的示例解析器,请转到此处.它解析了一个"jetLetter"文件,它只是groff/troff的一种方言.
虽然我不认为这是您的意图,但文件格式看起来与 Python 的内置ConfigParser模块非常相似。有时已经为您提供了最“Pythonic”的方式。(:
更直接地回答你的问题:正则表达式可能是一个很好的方法。否则,你可以尝试更基本的(和不太健壮的)
(parameter, value) = line.split('=')
Run Code Online (Sandbox Code Playgroud)
如果该行不包含一个或多个 '=' 字符,这将引发错误。您可能想先用'=' in line.
还:
line.find("[") == 1
Run Code Online (Sandbox Code Playgroud)
可能更好地替换为
line.startswith("[")
Run Code Online (Sandbox Code Playgroud)
希望有所帮助(:
| 归档时间: |
|
| 查看次数: |
2504 次 |
| 最近记录: |